恢复被CIH破坏的硬盘数据
没多长时间就又到4.26了,趁这日子俺也谈谈CIH发作后的数据恢复原理及方法:
CIH发作时先破坏Flash Memory,再写硬盘数据,直到写完整个硬盘为止,一般情况下,用户再病毒发作后数分钟内就已关机此时写盘代码还来不几写完整个硬盘,这也就是世面上哪些公司所讲的能恢复数据的原因。你可以试一下发作时几小时不关机,再拿去让他恢复,看看他能给你找会啥来。
能恢复数据原应已讲的很清楚。先假设用户在CIH发作后几分钟内关机。此时用俺写的《硬盘数据挽救者》只要填写原分区容量就可分分钟找回扩展分区数据,再加上点手工操作便可找回大部分C盘数据。因整个程序源代码太长,不便阅读,下面就以部分核心程序提取出来单写的一个汇编程序为列说一下恢复原理。
ode segment para public 'code'
org 100h
assume cs:code,ds:code,ss:code
start:
jmp init
tsr_start:
cmp dl,80h ;比较是否是C盘。
jnz go_oldint13
cmp ah,3 ;比较是否进行写操作。
jnz go_oldint13
cmp cx,1 ;比较是否写C盘的第一扇区。
jnz disable_write
cmp dh,0 ;比较是否写C盘的0面0道。(此处DH,1时禁止对WINDOWS引导扇区进行写操作)
jnz disable_write
go_oldint13:
jmp cs:dword ptr old_int13_off ;跳转到原始中断13H处继续执行其他操作 disable_write:
xor ah,ah ;AH=0设置正确操作AH的返回值,保证以下操作可继续执行。
push bp
mov bp,sp
mov bp,[bp+6] ;将堆栈基地址加6(也就是将堆栈指针加6)因执行INT13H时
; 将标志寄存器,IP指针,代码段CS,保存入栈每个寄存器在
; 堆栈中站2所以+6将3个寄存弹栈赋给BP,
push bp
popf ;将原始标志寄存器的值
pop bp
clc ;CF=0赋给现标志寄存器
retf 2
;以上操作是强行将CF=0以告诉计算机所执行的是正确的,如果CF=1有进位则为
; 错误,用FDISK时可能中途退出,
old_int13_off dw ? ;定义原INT13H偏移量
old_int13_seg dw ? ;定义原INT13H段地址
tsr_End: ;
tsr_length equ $-tsr_start
init:
xor ax,ax
mov es,ax
mov si,es:[13h*4] ;取INT 13在中断向量表中偏移量地址
cmp si,offset tsr_start ;比较程序是否已经运行
jnz not_stay
ret
not_stay:
mov old_int13_off,si
mov di,es:[13h*4+2]
mov old_int13_seg,di ;将中断向量表中INT 13替换为自己的INT 13处理程序
lea ax,tsr_start
mov es:[13h*4],ax
mov ax,cs
mov es:[13h*4+2],ax
mov ah,9
mov dx,offset message
int 21h
mov dx,offset tsr_end+1
int 27h ;执行程序并驻留。
code ends
end start
恢复方法首先运行此程序,再用FDISK进行分区后你会发现扩展分区数据已全部找回。
另:外行看热闹,内行看门道,之所以说CIH是种非常厉害病毒并不是因为他能破坏Flash Memory,而是他的编程手法非常高超且独特。在WIN下一般应用程序执行都是在Ring 3上,象对硬盘读写等低级操作须单独写一个VxD切换到Ring 0上运行。但如果这样做的话又失去了病毒意义。CIH使用了一种技术,采用Intel处理器 的中断从Ring 3转到Ring 0从而实现了VMM功能调用。俺没有很详细的读完全部CIH代码.说没有时间是给自己找借口,根本原因是俺现有水平有限,达不到能轻松理解的境界。 |