Type Multipartite virus
Creator Priest
Date Discovered 1993
Place of Origin United States
Source Language Assembly
Platform DOS
File Type(s) .com, .exe
Infection Length
Reported Costs

Jackal is a multipartite, memory resident virus by Priest. The virus is full-stealth and capable of infecting .com and .exe files under DOS as well as master boot records. The virus also has three payloads (one very malicious), including formatting the hard disk when a certain antivirus product is run.


When infecting the MBR only 3 bytes of the partition table are affected. Jackal reads the MBR and checks if it is bootable (0AA55h marker in last two bytes). Next it saves the affected 3 bytes of the partition table: start cylinder/sector and start head of the first partition. The virus then loads the first sector of this partition (boot sector) and checks if it is bootable (0AA55h marker) and if it is not already infected (infection marker).

Jackal then re-reads the MBR, calculates address of a last 7 sectors on the first physical track (using the 'last cylinder/sector' field of the first partition table entry), saves this sector address, saves 2 bytes at offset 01FEh of the virus and sets them to 0AA55h marker. Jackal then writes itself to the least 7 sectors of the first track then restores the bytes at offset 01FEh of the virus.

Finally the virus sets the first head, cylinder, track of the first partition of the MBR to the first sector of virus code and rewrites the MBR. This change of the partition table means that the first sector of the virus is read instead of the boot sector of the partition and that first sector loads the rest of the virus. Since the change to the partition table is hidden by Jackals stealth abilities, booting off a clean disk or attempting to disinfect the hard drive with 'FDISK /mbr' or any other utility that replaces the MBR code will leave the first partition inaccessible.

When loading from an infected MBR the Jackal sets the DS and register then allocates 5kb of memory by reducing 16-bit WORD at 0:413h (BIOS size of conventional memory). The virus then copies the first sector (512 bytes) of itself to this newly allocated memory and corrects the bytes that were patched with the 0AA55h marker. Jackal jumps to this new copy of its first sector and immediately loads the remaining 6 sectors of the virus from the end of the first track. If this read fails, the original boot sector of the partition is loaded and executed.

Jackal saves a copy of the entire IVT (interrupt vector table) in its memory - this is used to fake a warm reboot. The virus also saves the new value at 0:413h (BIOS size of conventional memory) for the same reason. Next the virus hooks INT 09h (Keyboard IRQ) and INT 13h (BIOS Disk Services). The INT 09h handler is used solely to fake the warm reboot: If ALT+CONTROL+DEL is pressed Jackal takes special action, otherwise control is released to the original INT 09h handler.

When faking a warm reboot, Jackal resets and enables the Keyboard hardware controller, restores the saved interrupt vector table, zeros its INT 21h vector, clears they keyboard flags and sets the value of 0:413h, sets video mode 03h and default cursor (using INT 10h), re-hooks INT 09h and INT 013h then finally issues an INT 19h (BIOS boot-strap loader). The INT 13h handler serves
two purposes: hooking INT 21h (MS-DOS API) when loading from the MBR, and stealthing the MBR. Hooking of INT 21h is achieved by checking the segment of the INT 21h vector on every INT 13h call. When it is is below 800h, INT 21h is hooked in the IVT and this check is disabled.

When running from an infected file Jackal immediately saves the 'CS' register and realigns CS:IP so that it is run from offset 0 using a 'RETF' instruction. This eliminates the need for use of a 'delta offset' register. The virus then sets two switches: one to tell its INT 13h handler not to check for INT 21h hook, and one to tell the virus to later tunnel and patch some interrupts. After this a routine is called to detect and disable 'TBCLEAN' (see "Payload" section). If 'TBCLEAN' is detected Jackal modifies its code to run the destructive payload instead of returning to the host when it is done.

Jackal then saves the entire IVT (interrupt vector table) and retrieves the segment of the first MCB (INT 21h/AH=52h - DOS List of Lists) and considers any thing below this segment as belonging to DOS when it tunnels interrupts. After this INT 13h, INT 21h, INT 15h and INT 40h are tunnelled using INT 01h single-stepping. In case of INT 21h, the MS-DOS handler is saved. In the case of INT 13h both MS-DOS and BIOS handlers are saved. In the case of INT 15h and INT 40h the BIOS handlers are saved. Jackals INT 01h handler emulates PUSHF/POPF/IRET/INT xx/INT3/INTO instructions to hide TF (Trace Flag) and to stop it from being cleared.

The virus then checks if it is already memory-resident. Jackal does not survive a warm reboot when loaded from a file infection, but is capable of this when running from a master boot record. Jackal then allocates memory: The virus checks that the hosts MCB (Memory Control Block) is the last in the chain and is big enough to allow allocation and then reduces it and 'Top Of Memory' field (offset +02h) of the host PSP (Program Segment Prefix). Jackal copies itself to this newly allocated memory and jumps to it, continuing execution.

Next Jackal infects the MBR (see above). The virus hooks INT 13h and INT 21h. Unlike loading from an MBR, file infections do not hook these interrupts in the Interrupt Vector Table. Instead the code of the tunnelled INT 13h and INT 21h MS-DOS handlers are patched with a 5-byte JMP FAR (0EAh) instruction each, pointing to the virus handlers.

Jackal then returns control to the host (or the TBCLEAN payload). The INT 21h handler of Jackal serves 4 purposes: the memory-residency check, to activate the payloads, to infect files and to stealth files. Files are infect on open, extended open, execute and close calls. When infecting on
'close' the virus first duplicates the handle (INT 21h/AH=45h). When infecting a file, Jackal resets the INT 13h, INT 15h and INT 40h vectors in the IVT to boot time or tunnelled values to bypass anti-virus software.

Antivirus Evasion

Jackal also uses System File Table (SFT) entries to avoid lseek/chmod/date/time calls in an attempt to reduce code size and by pass anti-virus software too. Finally, files are opened read-only and then the SFT entry is modified to read/write, again to bypass anti-virus software. Infected files are marked by adding 100 years to their time-stamp File infection is standard append to the end and modify the header type, except the virus is aligned on a 16-byte boundary so
the virus can re-align itself to offset 0 when loaded (see above), and the appropriate amount of padding is put between the end of the virus and the original file header to be used by the file stealth routines.

When infecting .COM files the Jackal checks for the .COM extension, when infecting .EXE files Jackal checks for 'MZ' or 'ZM' marker. When infecting .COM files Jackal avoids files beginning with suspicious code: If the first byte is 0 or NOP, HLT, CMC, CLC, STC or INT 20h (Terminate) instruction the file is avoided. Additionally if the file starts with "MOV AH,4Ch" or "MOV AX,4Cxxh" (Terminate Call), or "MOV AH,09h" or "MOV AX,09xxh" (Print string call) the file is
avoided. This might be to avoid bait files.


Stealth of the MBR is quite a simple process. After the MBR is read, if the first partition points to the first sector of the virus (reading in this sector and checking infection marker), the modified 3 bytes of the partition table are taken from the just read first sector of the virus and the read MBR is corrected. After hooking INT 09h and INT 13h, Jackals MBR loader code reads the original boot sector of the first partition and executes. If this read fails, an INT 18h (Transfer to ROM BASIC) is issued.

File stealth is performed on FCB FindFirst/FindNext calls, ASCII FindFirst/FindNext calls, read, write, lseek, and get/set date-stamp calls. In the case of FCB/ASCII FindFirst/FindNext calls, Jackal gets the current Disk Transfer Area (DTA) using INT 21h/AH=2Fh Jackal and hides the increase in file size and the 100 year marker in the file date-stamp In the case of read call, if all or part of the file header is read, Jackal replaces it with the original 'clean' header. If the read extends pass the end of the original file into the virus body Jackal truncates it at the end of the virus body.

In the case of a write call, the file is disinfected on disk before the write is done. If an lseek call is issued relative to the end of an infected file, it is instead done relative to the end of the original file, before the virus body. In the case of requests to get the file date-stamp, Jackal hides the 100 year marker. In the case of requests to set the date-stamp, Jackal ensures the 100 year marker is set if the file is infected.

Jackals INT 21h handler locks out the keyboard (Port 21h - IRQ Enable Mask) and re-enables it on exiting. This means that if an anti-virus monitor brings up a message, the user cannot respond and must reboot. When exiting the INT 21h handler, Jackal single-steps (INT 01h) 5 instructions before returning to the next INT 21h handler in the chain. It is this INT 01h handler that resets the INT 21h JMP FAR patch (if used, see above). This seems to be an attempt to stop anti-virus software from tunnelling through its code.

During INT 21h calls, Jackal points INT 24h (DOS Fatal Error Handler' to "MOV AL,3 / IRET" handler. This will return 'Fail' on fatal errors such as writing to a write-protected floppy, without any error messages.

Jackal includes the text string:


where '?' are extended ASCII characters. This is part of the code to load the
BX/CX/DX registers for the virus residency check. [1] [7] [8] [18]


Jackal is also a destructive virus, containing 3 separate destructive payloads. The condition for the first and most destructive payload is the most interesting: Jackal infected files are able to detect the presence of 'TBCLEAN' (the generic file disinfection utility of ThunderByte Anti-Virus), and disable its 'controlled environment'. When attempting to TBCLEAN a Jackal infected file, Jackal breaks out of TBCLEAN, locks the keyboard (port 21h, IRQ Enable Mask), trashes the CMOS (ports 70h, 71h), then entirely formats all hard drives reported by the BIOS then freeze the computer with 'CLI, HLT' series of instructions.

The other 2 payloads are executed periodically after a file is infected. Jackal maintains a counter of files that had been infected. If this counter value is a multiple of 32 after infecting the last file Jackal, implements its lesser payload: A random sector is read from the first hard drive, a random byte is modified in this sector, and the sector is re-written. This leads to slow, gradual corruption of the data on the hard drive.

The other destructive payload is called if this 'infection counter' is a multiple of 666h (1638 decimal): A randomly chosen track of the first hard drive is formatted Both these last 2 payloads are gradual and at times could go unnoticed. The last 2 payloads are only called if the BIOS INT 40h (Floppy Disk Services) vector is different from the BIOS INT 13h (Disk Services) vector. In all 3 payloads the (tunnelled) INT 13h vector is used to access the hard drive, bypassing anti-virus software.


Original research by JPanic aka @JPanicVX

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License