线程注入
来源:互联网 发布:linux下qt串口通信 编辑:程序博客网 时间:2024/05/16 09:08
下面是一段线程注入的源代码.写在这边,以后用起来方便.
要说这线程注入也就几个步骤.
1).获取宿主进程句柄
2).在宿主进程空间中申请地址空间
3).将预载入线程体写入宿主进程中
4).在宿主进程中创建线程.
这4个步骤就是进行线程注入的一般步骤.这里面当然也可以载入动态链接库.
这里还有一点需要说明:
每一个用户进程都有它自己私有的地址空间,也就是可以被那个进程访问的内存集合的区域.一个用户进程不可以直接访问另外一个用户进程的地址空间.属于用户进程的线程运行在用户级权限.
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
//#include "stdafx.h"
typedef struct _RemoteParam {
char szMsg[12]; //MessageBox函数中显示的字符提示
DWORD dwMessageBox;//MessageBox函数的入口地址
} RemoteParam, * PRemoteParam;
typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);
//根据进程名称得到进程的ID,如果有多个实例在同时运行的话,只返回第一个枚举到的进程ID
DWORD processNameToId(LPCTSTR lpszProcessName)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//为系统中所有进程建立一个快照
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnapshot, &pe))//进程获取函数,获取进程句柄
{
MessageBox(NULL,
"The frist entry of the process list has not been copyied to the buffer",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
while (Process32Next(hSnapshot, &pe)) //进程获取函数,获取下一个进程句柄
{
if (!strcmp(lpszProcessName, pe.szExeFile)) //如果找到该进程,则记录其进程ID
{
return pe.th32ProcessID;
}
}
return 0;
}
//要插入宿主进程中的线程函数
DWORD __stdcall threadProc(LPVOID lParam)
{
RemoteParam* pRP = (RemoteParam*)lParam;
PFN_MESSAGEBOX pfnMessageBox;
pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
pfnMessageBox(NULL, pRP->szMsg, pRP->szMsg, 0);
// TerminateProcess(GetCurrentProcess(),NULL);
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 dwThreadSize = 4096;
DWORD dwWriteBytes;
enableDebugPriv();
std::cout << "Please input the name of target process" << std::endl;
char szExeName[MAX_PATH] = { 0 };
//等待输入宿主进程名称
std::cin >> szExeName;
//得到指定名称进程的进程ID,如果有多个进程实例,则得到第一个进程ID
DWORD dwProcessId = processNameToId(szExeName);//根据进程名称,得到进程ID
HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);//打开一个已存在的进程对象。
if (!hTargetProcess)
{
MessageBox(NULL, "Open target process failed !",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
void* pRemoteThread = VirtualAllocEx(hTargetProcess, 0,
dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);//在宿主进程中申请一块存储区域
//把线程体写入宿主进程中
if (!WriteProcessMemory(hTargetProcess,
pRemoteThread, &threadProc, dwThreadSize, 0))
{
MessageBox(NULL, "Write data to target process failed !",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
//定义线程参数结构体变量
RemoteParam remoteData;
ZeroMemory(&remoteData, sizeof(RemoteParam));
//填充结构体变量中的成员
HINSTANCE hUser32 = LoadLibrary("User32.dll");
remoteData.dwMessageBox = (DWORD)GetProcAddress(hUser32, "MessageBoxA");
strcat(remoteData.szMsg, "Hello/0");
//为线程参数在宿主进程中开辟存储区域
RemoteParam* pRemoteParam = (RemoteParam*)VirtualAllocEx(
hTargetProcess , 0, sizeof(RemoteParam), MEM_COMMIT, PAGE_READWRITE);
if (!pRemoteParam) {
MessageBox(NULL, "Alloc memory failed !",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
//将线程参数拷贝到宿主进程地址空间中
if (!WriteProcessMemory(hTargetProcess ,
pRemoteParam, &remoteData, sizeof(remoteData), 0))
{
MessageBox(NULL, "Write data to target process failed !",
"Notice", MB_ICONINFORMATION | MB_OK);
return 0;
}
//在宿主进程中创建线程
HANDLE hRemoteThread = CreateRemoteThread(
hTargetProcess, NULL, 0, (DWORD (__stdcall *)(void *))pRemoteThread,
pRemoteParam, 0, &dwWriteBytes);
if (!hRemoteThread)
{
MessageBox(NULL, "Create remote thread failed !", "Notice", MB_ICONSTOP);
return -1;
}
CloseHandle(hRemoteThread);
return 0;
}
- 线程注入
- 线程注入
- 线程注入
- 线程注入
- 线程注入
- Dll注入-远线程注入
- 远程线程注入(二)线程注入
- 远程线程注入(二)线程注入
- 线程的远程注入
- 远程线程注入代码
- .net实现线程注入
- 远程注入线程
- 远程线程注入
- 线程远程注入
- 线程的远程注入
- 线程远程注入
- 线程注入模块--C++
- 远程线程dll注入
- 使用模板模板缓冲时需要注意的几个问题
- 中国区总裁的总部沟通术
- Resin禁止访问目录列表的配置方法
- [转]VIM的设置及插件安装
- JAVA程序员面试32问,你能回答多少题? (转)
- 线程注入
- SMTP and it’s Applications
- 体系结构的概念
- Yahoo YUI的Ajax工具包
- 数据迁移存储过程
- 获取硬盘序列号和卷标序列号
- 出错了.
- struts的option用法
- DataList控件也玩分页-转贴