;不能感染正在运行的文件(包括本身)。
;感染系统文件会造成非正常文件。
;没有没有异常处理。
;没有重定位等代码与修改程序入口。

.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include comdlg32.inc

includelib user32.lib
includelib kernel32.lib
includelib comdlg32.lib

.data
correy db "made by correy ",\
          "QQ:112426112 ",\
          "Email:leguanyuan@126.com ",\
          "Homepage:http://correy.webs.com",0;要写入节的数据。
FilterString db "pe File (*.exe, *.dll)",0,"*.exe;*.dll",0,0
sectionname db ".correy ",0;新加节的名字。同时也是感染标志。
Characteristics dword 0e0000020h ;新加节的属性。
wrong db "节头后面有数据,添加节失败。",0
infect db "文件已经感染!",0

.data?
ofn OPENFILENAME <> 
buffercmp db 40 dup (?)
buffersz db 40 dup (?)
buffer0 db 40 dup (?)
buffer db 256 DUP (?)
buffer1024 db 1027 DUP (?)
bufferorwrite db 1027 DUP (?)
;好多变量哟!我看了就晕,因为pe32文件太复杂了。
mz dd ?
pe dd ?
OptionalHeader dd ?
header dd ? 
sizeOfOptionalHeader dd ?
sizeofallheader dd ?
lsizeofallheader dd ?
sections dd ?
newheader dd ?;新添加节的节头的位置
lnewheader dd ? ;新添加节的节头的距离
hfile dd ?
lpe dd ? ;pe的距离
sectionalignment dd ?
filealignment dd ?
x dd ?
y dd ?
z dd ?
startwritecode dd ?
newsizeofrawdata dd ?
newsizeofcode dd ?
newsizeofimage dd ?
alignvirtualsize dd ?

.code

alignit proc sizes,aligns
push edx
mov eax,sizes
xor edx,edx
div aligns
cmp edx,0
je next
inc eax
next:mul aligns
pop edx
ret
alignit endp

start:
mov ofn.lStructSize,SIZEOF ofn 
mov ofn.lpstrFilter, OFFSET FilterString 
mov ofn.lpstrFile, OFFSET buffer 
mov ofn.nMaxFile,512 
mov ofn.Flags,00281804h
invoke GetOpenFileName, ADDR ofn 
invoke CreateFile,addr buffer,0c0000000h,3,0,3,80h,0
mov hfile,eax
invoke CreateFileMapping,eax,0,2,0,0,0
invoke MapViewOfFile,eax,4,0,0,0 
;没有判断是否是pe文件,有极少数带pe后缀名却非正常pe格式的。
mov mz,eax

mov esi,mz
add esi,3ch
mov esi,[esi]
mov lpe,esi
mov eax,mz
add esi,eax
mov pe,esi;"pe"的位置。

mov esi,pe
add esi,6
mov dx,word ptr [esi]
movsx edx,dx
mov sections,edx;节的数目。

mov esi,pe
add esi,24
mov OptionalHeader,esi ;可选头的地址。

mov esi,pe
add esi,20
mov dx,word ptr [esi]
movsx edx,dx
mov sizeOfOptionalHeader,edx;可选头的大小。

mov esi,pe
add esi,84
mov esi,[esi]
mov sizeofallheader,esi ;pe文件头的大小

mov eax,mz
add eax,sizeofallheader
mov lsizeofallheader,eax;第一个节的位置,也就是文件头的尾部。

mov esi,pe
add esi,56
mov esi,[esi]
mov sectionalignment,esi ;节对齐的尺寸。

mov esi,pe
add esi,60
mov esi,[esi]
mov filealignment,esi ;文件对齐的尺寸。

mov esi,OptionalHeader 
add esi,sizeOfOptionalHeader
mov header,esi ;保存节头的地址。

mov eax,40
mov ebx,sections
mul ebx
add eax,header
mov newheader,eax;预定新添加节的节头的位置
sub eax,mz
mov lnewheader,eax

;判断是否已经感染,感染标志是上一个节头的名字。
mov eax,newheader
sub eax,40
mov esi,eax
lea edi,sectionname
mov ecx,8
repe cmpsb
je infected

;判断预定的此位置是否可以使用。
;本人不善用scasb,所以定义个变量,用cmpsb.
lea esi,buffercmp
mov eax,mz
add eax,lnewheader
mov edi,eax
mov ecx,40
repe cmpsb
je startadd

;如果不想处理节头后面有数据的文件,可以在这里加入如下指令:
;jmp exit
;而直接退出。

;节头后面的数据,本人也忘记是啥数据了,有啥用与何用法。
;若处理节头后的数据,有可能导致文件不能运行。
;不足之处,敬请指导。
;系统文件的节头后大多有数据。

;如果节表的后面有数据,在这里(到startadd处)进行处理。

;节头的尾部到节的距离。
mov eax,sizeofallheader
sub eax,lnewheader
mov z,eax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;把节表后的数据反向复制到一个变量中。
mov ecx,eax

mov eax,mz
add eax,sizeofallheader

mov esi,eax
lea edi,buffer1024

strmov:
dec esi
inc edi
mov bl,byte ptr [esi]
mov byte ptr [edi],bl

dec ecx
cmp ecx,0
jne strmov
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ecx,-1
lea esi,buffer1024

zerocmp:
inc esi
inc ecx
mov al,byte ptr [esi]
cmp al,0
je zerocmp

cmp ecx,40
jb err

mov y,ecx;可用的空间

mov eax,z
sub eax,ecx
mov x,eax;节表后的可用的字符数。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;复制要写的内容(节表后面的)。
mov ecx,z

inc ecx

mov eax,mz
add eax,lnewheader

mov esi,eax
lea edi,bufferorwrite

dec esi
dec edi

movstr:
inc esi
inc edi
mov bl,byte ptr [esi]
mov byte ptr [edi],bl

dec ecx
cmp ecx,0
jne movstr
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;置新节表的数据全为0
invoke SetFilePointer,hfile,lnewheader,0,0
invoke WriteFile,hfile,addr buffer0,40,addr buffer,0
;把节表后的数据后移40位字节。
invoke WriteFile,hfile,offset bufferorwrite,x,addr buffer,0

startadd:
;设置节的数量。
mov eax,lpe
add eax,6
invoke SetFilePointer,hfile,eax,0,0
inc sections
invoke WriteFile,hfile,addr sections,2,addr buffer,0

;设置节的名字。
invoke SetFilePointer,hfile,lnewheader,0,0
invoke WriteFile,hfile,addr sectionname,8,addr buffer,0

;设置新加节的virtualsize
invoke lstrlen,addr correy
mov x,eax
invoke WriteFile,hfile,addr x,4,addr buffer,0
push sectionalignment
push x
call alignit
mov alignvirtualsize,eax

;设置新加节的virtualaddress
;实现方法是假设最后一个节头的virtualaddress最大。
;等于上一个节表的某两项之和。
mov eax,newheader
sub eax,28
mov eax,[eax]
mov y,eax

mov eax,newheader
sub eax,32
mov eax,[eax]
mov x,eax

push sectionalignment
push x
call alignit
add eax,y
mov y,eax
invoke WriteFile,hfile,addr y,4,addr buffer,0

;设置新加节的sizeofrawdata
push filealignment
push x
call alignit
mov newsizeofrawdata,eax
invoke WriteFile,hfile,addr newsizeofrawdata,4,addr buffer,0

;设置新加节的pointertorawdata
mov eax,newheader
sub eax,20
mov eax,[eax]
mov x,eax
mov eax,newheader
sub eax,24
mov eax,[eax]
add eax,x
mov startwritecode,eax
invoke WriteFile,hfile,addr startwritecode,4,addr buffer,0

;设置节的属性
mov eax,lnewheader
add eax,36
invoke SetFilePointer,hfile,eax,0,0
invoke WriteFile,hfile,addr Characteristics,4,addr buffer,0

;修改可选头的sizeofcode
mov eax,pe
add eax,28
mov eax,[eax]
add eax,newsizeofrawdata;alignvirtualsize;
mov newsizeofcode,eax
mov ebx,lpe
add ebx,28
invoke SetFilePointer,hfile,ebx,0,0
invoke WriteFile,hfile,addr newsizeofcode,4,addr buffer,0

;修改可选头的sizeofimage
mov eax,pe
add eax,80
mov eax,[eax]
add eax,alignvirtualsize;newsizeofrawdata
mov newsizeofimage,eax
mov ebx,lpe
add ebx,80
invoke SetFilePointer,hfile,ebx,0,0
invoke WriteFile,hfile,addr newsizeofimage,4,addr buffer,0

;修改程序的入口点
;这点不写了吧!

;写文件
invoke SetFilePointer,hfile,startwritecode,0,0
invoke WriteFile,hfile,addr correy,sizeof correy,addr buffer,0

mov eax,newsizeofrawdata
add eax,startwritecode
push eax
invoke SetFilePointer,hfile,eax,0,0

pop eax
sub eax,sizeof correy
invoke SetFilePointer,hfile,eax,0,0
invoke WriteFile,hfile,addr correy,sizeof correy,addr buffer,0

invoke FlushFileBuffers,hfile
invoke CloseHandle,hfile
jmp exit

infected:
invoke MessageBox,0,addr infect,0,0
jmp exit

err:
invoke MessageBox,0,addr wrong,0,0

exit:
invoke ExitProcess,NULL
end start
;made at 2010.07.14

上传的附件 windows.rar