• 标 题:用进程注入来实现一个壳(原理)
  • 作 者:simonzh2000
  • 时 间:004-06-02,13:26
  • 链 接:http://bbs.pediy.com

用进程注入来实现一个壳(原理)

作者: Simonzh2000[US]

感谢 too2y , 老王.
这是我在学习老王的壳后, 参考网上的一些例子做的。
比老王的壳差的太远, 希望各位不要见笑.
如果各位写出了类似的加壳器, 希望发一个给我。

启动前先启动 Calc.exe, 改一下, 用 Explorer.exe 也可以。

#define UNICODE
#define _UNICODE
                          
#include <windows.h>
#include <tchar.h>
#include <conio.h>
#include <psapi.h>

typedef struct _remoteparameter
{
  DWORD       rpwinexec;
  DWORD       rpcreatemutex;
  DWORD       rpsleep;
  DWORD       rpclosehandle;

  char        rpwinexecname[MAX_PATH];
    HANDLE      rphMutex;
    TCHAR       rpMutex[30];
  
}REMOTEPARAMETER, *PREMOTEPARAMETER;

DWORD   WINAPI remote(LPVOID);
DWORD   processtopid(TCHAR*);  
HANDLE  createremote(PTSTR);     


TCHAR             cMutex[8];


int main()
{
   TCHAR             ExeName[MAX_PATH];
  HANDLE            hRemoteThread;
  HANDLE            hMutex;
  int               ret; 

    _tcscpy(cMutex,_T("simonzh"));
  hMutex = OpenMutex(SYNCHRONIZE, TRUE, cMutex );
  if (hMutex == NULL)
  {
    ret=GetModuleFileName(NULL,ExeName,MAX_PATH);
    if(ret==0)
    {
      OutputDebugString(_T("GetModuleFileName Error\n"));
      getche();              
      return -1;
    }

 
    if((hRemoteThread=createremote(ExeName))==NULL)   
    {
      OutputDebugString(_T("CreateRemote Error\n"));
      getche();              
        return -1;
    }
        
    return 0;
  }

  CloseHandle(hMutex);
   
  // 上面相当于一个壳的 Loader 
           // 下面相当于被加壳的原程序.
  _tprintf(_T("---[ This is not me.   HaHaHa... ]---\n"));   
  getche();
  return 0;
}
    

DWORD processtopid(TCHAR *processname)
{
  DWORD    lpidprocesses[1024],cbneeded,cprocesses;
  HANDLE   hprocess;
  HMODULE  hmodule;
  UINT     i;
  TCHAR    normalname[MAX_PATH]=_T("UnknownProcess");
    
  if(!EnumProcesses(lpidprocesses,sizeof(lpidprocesses),&cbneeded))
  {
    OutputDebugString(_T("EnumProcesses Error\n"));
    return -1;  
  }

  cprocesses=cbneeded/sizeof(DWORD);
  
  for(i=0;i<cprocesses;i++)
  {
    hprocess=OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,lpidprocesses[i]);
    if(hprocess)
    {
      if(EnumProcessModules(hprocess,&hmodule,sizeof(hmodule),&cbneeded))
      {
        GetModuleBaseName(hprocess,hmodule,normalname,sizeof(normalname));
        if(!_tcsicmp(normalname,processname))  
        {
          CloseHandle(hprocess);
          return (lpidprocesses[i]);
        }
      }
    }

  }

  CloseHandle(hprocess);
  return 0;
}


HANDLE createremote(PTSTR ExeName)
{
    HANDLE            ethread;
  HANDLE            rphandle;
  TCHAR             name[15];
  TCHAR             *remotethr;
  TCHAR             *remotepar;
  DWORD             remotepid;
  int               cb;
  HINSTANCE         hkernel32;
  REMOTEPARAMETER   rp;

  _tcscpy(name,_T("Calc.exe"));

  
  while(1)
  {
    remotepid=processtopid(name); 
    
    if(remotepid==-1)
    {
      return NULL;
    }
    else if(remotepid==0)
    {
      OutputDebugString(_T("Remote Process isn't running\n")); 
      Sleep(1000);
      continue;
    }


      rphandle=OpenProcess(PROCESS_CREATE_THREAD |     
                           PROCESS_VM_OPERATION  |     
                    PROCESS_VM_WRITE,           
                 FALSE,remotepid);
      if(rphandle==NULL)
    {
        Sleep(1000);
      continue;
    }
    else
    {
      break; 
    }
  }

  cb=sizeof(TCHAR)*4*1024;
  remotethr=(PTSTR)VirtualAllocEx(rphandle,NULL,cb,MEM_COMMIT,PAGE_EXECUTE_READWRITE); 
  if(remotethr==NULL)
  {
    OutputDebugString(_T("VirtualAllocEx for Thread Error\n"));
        CloseHandle(rphandle);       
    return NULL;
  }

    if(WriteProcessMemory(rphandle,remotethr,(LPVOID)remote,cb,NULL)==FALSE)
  {
    OutputDebugString(_T("WriteProcessMemory for Thread Error\n"));
        CloseHandle(rphandle);
    return NULL;
  }

  {   
    memset(&rp,0,sizeof(rp));
        _tcscpy(rp.rpMutex, cMutex);
    WideCharToMultiByte(CP_ACP,0,ExeName,-1,rp.rpwinexecname,_tcslen(ExeName),NULL,NULL);
    
    hkernel32=GetModuleHandle(_T("kernel32.dll"));
    rp.rpwinexec=(DWORD)GetProcAddress(hkernel32,"WinExec");
    rp.rpcreatemutex=(DWORD)GetProcAddress(hkernel32,"CreateMutexW");
    rp.rpsleep=(DWORD)GetProcAddress(hkernel32,"Sleep");
    rp.rpclosehandle=(DWORD)GetProcAddress(hkernel32,"CloseHandle");
  }   
  
  cb=sizeof(TCHAR)*sizeof(rp);
  remotepar=(PTSTR)VirtualAllocEx(rphandle,NULL,cb,MEM_COMMIT,PAGE_READWRITE);
  if(remotepar==NULL)
  {
    OutputDebugString(_T("VirtualAllocEx for Parameter Error\n"));
    CloseHandle(rphandle);
    return NULL;
  }

  if(WriteProcessMemory(rphandle,remotepar,(LPVOID)&rp,cb,NULL)==FALSE)
  {
    OutputDebugString(_T("WriteProcessMemory for Parameter Error:"));
    CloseHandle(rphandle);
    return NULL;
  }
    
  
  ethread=CreateRemoteThread(rphandle,NULL,0,(LPTHREAD_START_ROUTINE)remotethr,(LPVOID)remotepar,0,NULL);
  if(ethread==NULL)
  {
    OutputDebugString(_T("CreateRemoteThread Error\n"));
    CloseHandle(rphandle);
    return NULL;
  }

  return ethread;
}


DWORD WINAPI remote(LPVOID pvparam)
{
  PREMOTEPARAMETER erp=(PREMOTEPARAMETER)pvparam;

    typedef UINT   (WINAPI *EWinExec)(LPCSTR, UINT);
  typedef HANDLE (WINAPI *ECreateMutex)(LPSECURITY_ATTRIBUTES , BOOL, LPCTSTR);
   typedef VOID   (WINAPI *ESleep)(DWORD);
    typedef BOOL   (WINAPI *ECloseHandle)(HANDLE);
  
  EWinExec             tWinExec;
    ECreateMutex         tCreateMutex;
    ESleep               tSleep;
  ECloseHandle         tCloseHandle;

  tWinExec=(EWinExec)erp->rpwinexec;
  tCreateMutex=(ECreateMutex)erp->rpcreatemutex;
  tSleep=(ESleep)erp->rpsleep;
  tCloseHandle=(ECloseHandle)erp->rpclosehandle;

  erp->rphMutex=tCreateMutex(NULL, TRUE, erp->rpMutex);

  if(tWinExec(erp->rpwinexecname, SW_SHOW)<=31)             
  {
    return -1;
  }
    
  tSleep(4000);
  tCloseHandle(erp->rphMutex);
  return 0;
}