CIH病毒
木子石
作为首例WIN32病毒,CIH 感染32位后缀为.EXE的PE格式可执行文件,当染毒文件在Windows
9x下首次执行时,它将驻留内存、监视之后所有的打开文件操作并传染,由于WindowsNT并不支持其用到的技术,因此染毒文件在NT下无法执行。下面我们以CIH
V1.2为例进行分析,最后给出一个CIH免疫程序。
首先给出CIH的伪代码:
vir_entry_point:
push 结构化例外处理链
push EAX
sidt FWORDPTR[ESP-2]
pop ebx
;获取中断描述符表(IDT)基址
CLI
;关中断
保存int 3入口地址
设置新int 3入口为new_int3_isr
int 3
;调用int 3使CPU由特权级3转入特权级0
将病毒拷贝至分配的系统内存页中
int 3
;在特权级0下常驻内存
vir_exit:
STI;开中断
pop 结构化例外处理链
push EXE染毒前的程序入口点
RET;转至程序正常执行处
new_int3_isr:
若已将病毒拷贝至分配的系统内存页中,
jmp to install_hook
mov ECX,DR0;读取系统染毒标志
JECXZ alloc_mem_and_prepare_to_infect
CIH认为系统已染毒,
调整栈顶的int 3返回地址为vir_exit
恢复原来int 3入口地址
IRETD;转至vir_exit处
alloc_mem_and_prepare_to_infect:
调用_PageAllocate分配2页系统内存
IRETD
install_hook:
LEA EAX,file_hook
VXDCall IFSMgr_InstallFileSystemApiHook
mov DR0,EAX
;将下一hook的入口点
保存在DR0中作为
;系统是否染毒的标志。
恢复原来int 3入口地址
jmp vir_exit
file_hook:
PUSHAD;保护现场
判断是否打开文件操作(IFSFN_OPEN),文件后缀是否为.EXE,该文件是否已经染毒(通过PE格式文件的PE标志头的前一字节为0否判别)。若条件全部满足则试图感染该EXE文件
判断是否为4月26日,若是则试图破坏硬盘及BIOS。
POPAD;恢复现场
mov EAX,DR0
jmp [EAX];继续下一个hook
CIH两次int 3调用的目的是使CPU由用户态的特权级3转入特权级0,从而能够在核心态进行操作系统级的调用,完成系统内存的分配和文件系统hook的安装。
通过分析,我们知道CIH v1.2没有使用任何反跟踪或变形技术。它通过检查调试寄存器0(DR0)来决定系统是否已被感染;通过检查PE标志头的前一字节决定该文件是否已被感染。基于此,我们可以写一个简单的免疫程序段,它可嵌到C程序中:
#define FLAG 0x12345678
DWORD rDR0;
_asm{
pushad ;保护现场
push ebx
sidt fword ptr [esp -2]
pop ebx
;获取中断描述符表基址
add ebx,0x1c
cli
mov edx,[ebx]
mov dx,[ebx -4]
;保存int 3入口地址
lea ecx,int3_isr
mov [ebx -4],cx
shr ecx,0x10
mov [ebx +2],cx
;设置新int 3入口为int3_isr
int 3
jmp ok
int3_isr:
mov eax,dr0
;在特权级0读取系统染毒标志
mov ecx,FLAG
mov dr0,ecx
iretd
ok:
mov rDR0,eax
mov [ebx -4],dx
shr edx,0x10
mov [ebx +2],dx
;恢复原来int 3入口地址
sti
popad
;恢复现场
}
if(0==rDR0) printf
(“疫苗安装成功。”);
else if(FLAG==rDR0) printf
(“疫苗已经安装。”);
else printf
(“系统可能已被CIH感染!!
DR0=%lx”,rDR0);
此方法通过设置调试寄存器DR0为非0使CIH误以为系统已被感染。对于一个干净的Windows
95/98系统,执行上述程序段后系统就不会被CIH感染,并且可以安全执行被CIH感染的EXE文件。