创建远程线程注入指定进程

 

创建远程线程使用CreateRemoteThread函数,在创建线程前还需要使用WriteProcessMemory等函数将线程
函数代码和参数写到目标进程空间中去.

关键API
CreateRemoteThread
为指定进程创建线程,线程将会在其他进程的进程空间中执行,访问其他进程资源.
HANDLE WINAPI CreateRemoteThread(
__in HANDLE hProcess,
__in LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out LPDWORD lpThreadId
);

hProcess:输入参数,需要为其创建线程的目标进程句柄.

The following table lists the process-specific access rights.
Value Meaning
PROCESS_ALL_ACCESS All possible access rights for a process object.
PROCESS_CREATE_PROCESS (0x0080) Required to create a process.
PROCESS_CREATE_THREAD (0x0002) Required to create a thread.
PROCESS_DUP_HANDLE (0x0040) Required to duplicate a handle using DuplicateHandle.
PROCESS_QUERY_INFORMATION (0x0400) Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob).
PROCESS_QUERY_LIMITED_INFORMATION (0x1000) Required to retrieve certain information about a process (see QueryFullProcessImageName). If you are granted PROCESS_QUERY_INFORMATION, you are also granted PROCESS_QUERY_LIMITED_INFORMATION.
PROCESS_SET_INFORMATION (0x0200) Required to set certain information about a process, such as its priority class (see SetPriorityClass).
PROCESS_SET_QUOTA (0x0100) Required to set memory limits using SetProcessWorkingSetSize.
PROCESS_SUSPEND_RESUME (0x0800) Required to suspend or resume a process.
PROCESS_TERMINATE (0x0001) Required to terminate a process using TerminateProcess.
PROCESS_VM_OPERATION (0x0008) Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory).
PROCESS_VM_READ (0x0010) Required to read memory in a process using ReadProcessMemory.
PROCESS_VM_WRITE (0x0020) Required to write to memory in a process using WriteProcessMemory.
SYNCHRONIZE (0x00100000L) Required to wait for the process to terminate using the wait functions.
权限参照CreateThread函数
返回HANDLE值,为新创建进程的句柄

 

WriteProcessMemory
WriteProcessMemory函数可以将数据写入到目标进程的虚拟地址空间中.
BOOL WriteProcessMemory(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesWritten
);


hProcess:输入参数,目标进程句柄,操作进程需要有目标进行的PROCESS_VM_WRITE和PROCESS_VM_OPERATION权限
lpBaseAddress:输入参数,写入数据地址,目标进程虚拟空间中的地址.
lpBuffer:输入参数,指向需要写入的数据
nSize:输入参数,写入数据大小,字节
lpNumberOfBytesWritten:输出参数,指向SIZE_T类型的变量,用于保存实际写入的数据大小.
返回值
失败用GetLastError函数获取错误信息

 

/* 头文件 */
#include <windows.h>
#include <Tlhelp32.h>

/*************************************
* BOOL EnablePrivilege (PCSTR name)
* 功能 提升本权限
*
* 参数 PCSTR name 所需的权限
* 返回是否成功
**************************************/
DWORD EnablePrivilege (PCSTR name)
{
HANDLE hToken;
BOOL rv;
//设置结构
TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} };
// 查找权限值
LookupPrivilegeValue (
   0,
   name,
   &priv.Privileges[0].Luid
   );
// 打开本进程Token
OpenProcessToken(
   GetCurrentProcess (),
   TOKEN_ADJUST_PRIVILEGES,
   &hToken
   );
// 提权
AdjustTokenPrivileges (
   hToken,
   FALSE,
   &priv,
   sizeof priv,
   0,
   0
   );
// 返回值,错误信息,如果操作成功,则应为ERROR_SUCCESS,为O
rv = GetLastError();
// 关闭Token
CloseHandle (hToken);
return rv;
}

/*************************************
* BOOL LoadRometeDll(DWORD dwProcessId, LPTSTR lpszLibName)
* 功能 通过创建远程线程给其他进程加载Dll
*
* 参数 DWORD dwProcessId 目标进程PID
*   LPTSTR lpszLibName Dll的路径
* 返回是否成功
**************************************/
BOOL LoadRometeDll(DWORD dwProcessId, LPTSTR lpszLibName)
{
BOOL   bResult          = FALSE; 
HANDLE hProcess         = NULL;
HANDLE hThread          = NULL;
PSTR   pszLibFileRemote = NULL;
DWORD cch;
PTHREAD_START_ROUTINE pfnThreadRtn;

__try 
{
   // 获得想要注入代码的进程的句柄.
   hProcess = OpenProcess(
    PROCESS_ALL_ACCESS, 
    FALSE, 
    dwProcessId
    );

   if (hProcess == NULL)
    __leave;

   // 计算DLL路径名需要的字节数.
   cch = 1 + lstrlen(lpszLibName);

   // 在远程线程中为路径名分配空间.
   pszLibFileRemote = (PSTR)VirtualAllocEx(
    hProcess, 
    NULL, 
    cch, 
    MEM_COMMIT, 
    PAGE_READWRITE
    );

   if (pszLibFileRemote == NULL) 
    __leave;

   // 将DLL的路径名复制到远程进程的内存空间.
   if (!WriteProcessMemory(
    hProcess, 
    (PVOID)pszLibFileRemote, 
    (PVOID)lpszLibName, 
    cch, 
    NULL)) 
    __leave;

   // 获得LoadLibraryA在Kernel32.dll中的真正地址. 
   pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(
    GetModuleHandle(TEXT("Kernel32")), TEXT("LoadLibraryA"));

   if (pfnThreadRtn == NULL) 
    __leave;

   // 创建远程线程,并通过远程线程调用用户的DLL文件. 
   hThread = CreateRemoteThread(
    hProcess, 
    NULL, 
    0, 
    pfnThreadRtn, 
    (PVOID)pszLibFileRemote, 
    0, 
    NULL
    );
   if (hThread == NULL) 
    __leave;

   // 等待远程线程终止.
   WaitForSingleObject(hThread, INFINITE);
   bResult = TRUE; 
}
__finally 
{ 
   // 关闭句柄. 
   if (pszLibFileRemote != NULL) 
    VirtualFreeEx(hProcess, (PVOID)pszLibFileRemote, 0, MEM_RELEASE);
   if (hThread != NULL) 
    CloseHandle(hThread);
   if (hProcess != NULL) 
    CloseHandle(hProcess);
}
return bResult;
}
/*************************************
* BOOL GetProcessIdByName(LPSTR szProcessName, LPDWORD lpPID)
* 功能 通过进程名获取进程PID
*
* 参数 LPSTR szProcessName 进程名
*   LPDWORD lpPID   指向保存PID的变量
* 返回是否成功
**************************************/
BOOL GetProcessIdByName(LPSTR szProcessName, LPDWORD lpPID)
{
// 变量及初始化
STARTUPINFO st;
PROCESS_INFORMATION pi;
PROCESSENTRY32 ps;
HANDLE hSnapshot;
ZeroMemory(&st, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
st.cb = sizeof(STARTUPINFO);
ZeroMemory(&ps,sizeof(PROCESSENTRY32));
ps.dwSize = sizeof(PROCESSENTRY32);
// 遍历进程
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0);
if(hSnapshot == INVALID_HANDLE_VALUE)
{
   return FALSE;
}

if(!Process32First(hSnapshot,&ps))
{
   return FALSE;
}
do
{
   // 比较进程名
   if(lstrcmpi(ps.szExeFile,"explorer.exe")==0)
   {
    // 找到了
    *lpPID = ps.th32ProcessID;
    CloseHandle(hSnapshot);
    return TRUE;
   }
}
while(Process32Next(hSnapshot,&ps));
// 没有找到
CloseHandle(hSnapshot);
return FALSE;
}
/*************************************
* int WinMain(
*    HINSTANCE hInstance,
*    HINSTANCE hPrevInstance,
*    LPSTR lpCmdLine,
*    int nCmdShow
*    )
**************************************/
int WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
    )
{
DWORD dwPID;
// 提权,获取SE_DEBUG_NAME权限,
// 可以在其他进程的内存空间中写入、创建线程
if(0!=EnablePrivilege (SE_DEBUG_NAME))
   return 0;
// 获取目录进程的PID
if(!GetProcessIdByName("explorer.exe",&dwPID))
   return 0;
// 通过创建远程线程加载DLL
// 将msg.dll放置在系统目录下
if(!LoadRometeDll(dwPID,"msg.dll"))
   return 0;
return 1;
}

msg文件创建msg.dll文件
/* 头文件 */
#include <Windows.h>
#include <Psapi.h>
/* 链接 */
#pragma comment (lib, "Psapi.lib") 
/* 函数声明 */

// 使用__declspec(dllexport)声明导出函数
__declspec(dllexport) DWORD ExportExample(LPSTR szMsg, DWORD dwCode);

/*************************************
* DllMain
**************************************/
BOOL WINAPI DllMain(
      HINSTANCE hinstDLL, // DLL模块的句柄
      DWORD fdwReason,     // 调用的情况
      LPVOID lpReserved ) // reserved
{
// 在不同的情况下都会调用DllMain函数,分别处理
switch( fdwReason ) 
{ 
   // 加载Dll
   case DLL_PROCESS_ATTACH:
   {
    CHAR lpMainMoudleName[MAX_PATH];
    CHAR lpMessage[MAX_PATH+64];
    // 获取PID 和主模块名,将弹出消息框
    DWORD dwPID = GetCurrentProcessId();
    GetModuleBaseName(GetCurrentProcess(),NULL,lpMainMoudleName,MAX_PATH);
    wsprintf(lpMessage,"Process name: %s, PID: %u ",lpMainMoudleName,dwPID);
    MessageBox(NULL,lpMessage,"msg.dll",MB_OK);
    break;
   }
   // 新建线程
case DLL_THREAD_ATTACH:
   break;
   // 线程退出
case DLL_THREAD_DETACH:
   break;
   // 释放Dll
case DLL_PROCESS_DETACH:

   break;
}
return TRUE;
}

/*************************************
* DWORD ExportExample(LPSTR szMsg, DWORD dwCode)
* 功能 导出函数,显示消息
*
* 参数 LPSTR szMsg 字符串; DWORD dwCode 整形
**************************************/
DWORD ExportExample(LPSTR szMsg, DWORD dwCode)
{
LPVOID lpShowOut = HeapAlloc(GetProcessHeap(), 0, lstrlen(szMsg)+100);
wsprintf(lpShowOut,"%s,%d",szMsg,dwCode);
MessageBox(NULL,lpShowOut,"由导出函数弹出的消息!",MB_OK);
HeapFree(GetProcessHeap(), 0, lpShowOut);
return 0;
}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值