线程远程注入

来源:互联网 发布:淘宝店铺二维码名片 编辑:程序博客网 时间:2024/05/20 02:30

线程远程注入的技术并不复杂,主要用到CreateRemoteThread这个API。难点有个地方,由于要注入其他进程的空间,因此,注入用的那个线程中的代码必须使用和被注入进程的内存空间一致。换句话讲,就是需要找到线程中使用的函数在远程进程中的地址。明白这个,问题就没有了。下面是一个完整的线程注入的代码,在XP+SP3下运行成功。很简单的代码。

 

#include <stdio.h>
#include "WTYPES.H"
//typedef unsigned long DWORD;// 为了在程序中使用DWORD,可以include WTYPES.H,也可以使用该行定义

//先定义参数结构  
typedef   struct   _RemotePara{//参数结构  
 char   pMessageBox[12];  
 DWORD   dwMessageBox;  
 }RemotePara, * RemoteParam;  

//定义MessageBox类型的函数指针
typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);


//线程函数定义
int __stdcall ThreadProc   (void   *lpPara){  
 
 RemotePara* pRP = (RemotePara*)lpPara;
 PFN_MESSAGEBOX pfnMessageBox;
 pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
 pfnMessageBox(NULL, pRP->pMessageBox, pRP->pMessageBox, 0);
 
    return 0;
 
  }  

//提升进程访问权限
bool enableDebugPriv()
{
 HANDLE hToken;
 LUID sedebugnameValue;
 TOKEN_PRIVILEGES tkp;
 if (!OpenProcessToken(GetCurrentProcess(),
  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
  return false;
 }
 
 if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
  CloseHandle(hToken);
  return false;
 }
 
 tkp.PrivilegeCount = 1;
 tkp.Privileges[0].Luid = sedebugnameValue;
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
 if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
  CloseHandle(hToken);
  return false;
 }
 
 return true;
}

 

int   main(int   argc,   char*   argv[])
{
 const   DWORD   THREADSIZE=1024*4;//暂定线程体大小为4K
  DWORD   byte_write;
  //提升进程访问权限
  enableDebugPriv();


  HANDLE   hWnd   =   ::OpenProcess   (PROCESS_ALL_ACCESS,FALSE,3196);  //打开PID为3196的进程
  if(!hWnd)
   printf("error OpenProcess!/n ");  

  void   *pRemoteThread   =::VirtualAllocEx(hWnd,0,THREADSIZE,MEM_COMMIT|   MEM_RESERVE,PAGE_EXECUTE_READWRITE);//在宿主进程中使用VirtualAllocEx函数申请一段内存  
  if(!pRemoteThread)
   printf("error VirtualAllocEx!/n"); 

  //将线程体拷贝到宿主进程中
  if(!::WriteProcessMemory(hWnd,pRemoteThread,&ThreadProc,THREADSIZE,0))
   printf("error WriteProcessMemory!/n");

//定义线程参数结构体变量
  RemotePara   myRemotePara;  
  ::ZeroMemory(&myRemotePara,sizeof(RemotePara)); 
  //填充结构体变量中的成员
  HINSTANCE   hUser32   =   ::LoadLibrary   ("User32.dll");  
  myRemotePara.dwMessageBox   =(DWORD)   ::GetProcAddress   (hUser32   ,   "MessageBoxA");  
  strcat(myRemotePara.pMessageBox,"hello/0");  

  //为线程参数在宿主进程中开辟存储区域
  RemotePara* pRemoteParam = (RemotePara*)VirtualAllocEx(
   hWnd , 0, sizeof(RemoteParam), MEM_COMMIT, PAGE_READWRITE);
  if(!pRemoteParam)
   printf("error VirtualAllocEx!/n"); 

//将线程参数拷贝到宿主进程地址空间中
  if (!WriteProcessMemory(hWnd ,
   pRemoteParam, &myRemotePara, sizeof(myRemotePara), 0)) {
   MessageBox(NULL, "Write data to target process failed !",
    "Notice", MB_ICONINFORMATION | MB_OK);
   return 0;
  }

 

  //启动线程  
  HANDLE   hThread   =   ::CreateRemoteThread   (hWnd   ,0,0,(DWORD   (__stdcall   *)(void   *))pRemoteThread   ,pRemoteParam,0,&byte_write);  
  if(!hThread){   //还有内存分配未释放  
   printf("error CreateRemoteThread!/n");  
  }  
 
CloseHandle(hThread);
  return 0;
}