概述
昨天晚上找到了个有意思的API CreateRemoteThread(),它可以在别的进程中创建自己需要的线程,我想这个函数在做坏事上肯定很拿手哈~,当然,技术没有好坏,用得好是天使,用得坏是魔鬼,关键在于人。
许多API是值得花时间看的,虽然不好懂,但作用强大,因此这里总结一下这个函数的心得,以后若忘了也容易捡起来。
1:我们的目的是这样的:我们启动进程A,让A在进程B中增加一个线程S,然后进程A结束,然后S在B中正常工作,比如说打印一条"hello world“。
2:这个过程遇到了些问题,下面简要说明下:
(1):进程B中需要为新线程S添加2个区域,即CODE段和DATA段,让我们想想单纯的汇编中的CODE SEGMENT和DATA SEGMENT。CODE段大小直接为一页即可,不就4KB嘛,没必要计算CODE的真正空间大小。
(2):DATA段是必须的,除非你的线程函数不调用其他函数(这样没什么意思吧),DATA段通常传入一个自定义结构,这个结构非常重要,所有的操作都在结构里面了。
(3):只要搞定了这2个段,就可以CreateRemoteThread了,但还有一些细节问题需要注意,比如如何通过进程名(任务管理器)得到进程ID,进而得到句柄,比如如何加载DLL(我前面刚讲DLL哈~)。
3:最后还有一个问题,请不要使用DEBUG模式执行,请在Release下编译链接执行,否则你的B就有危险了!
参考代码如下:(转自http://blog.csdn.net/vcforever/archive/2005/03/15/319872.aspx,我这里省了许多东西,目的是为了更加清楚的看清流程,请原作者勿怪,对了,请把QQ打开哈)
// Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#pragma comment(lib, "advapi32.lib")
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
using namespace std;
//线程参数结构体定义
typedef struct _RemoteParam {
char szMsg[12]; //MessageBox函数中显示的字符提示
DWORD dwMessageBox;//MessageBox函数的入口地址
} RemoteParam, * PRemoteParam;
//定义MessageBox类型的函数指针
typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);
//线程函数定义
DWORD __stdcall threadProc(LPVOID lParam)
{
RemoteParam* pRP = (RemoteParam*)lParam;
PFN_MESSAGEBOX pfnMessageBox;
pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox;
pfnMessageBox(NULL, pRP->szMsg, pRP->szMsg, 0);
return 0;
}
//根据进程名称得到进程ID,如果有多个运行实例的话,返回第一个枚举到的进程的ID
DWORD processNameToId(LPCTSTR lpszProcessName)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnapshot, &pe)) {
return 0;
}
while (Process32Next(hSnapshot, &pe)) {
if (!strcmp(lpszProcessName, pe.szExeFile)) {
return pe.th32ProcessID;
}
}
return 0;
}
int main(int argc, char* argv[])
{
//定义线程体的大小
const DWORD dwThreadSize = 4096;
DWORD dwWriteBytes;
//等待输入进程名称,注意大小写匹配
DWORD dwProcessId = processNameToId("QQ.exe");
//根据进程ID得到进程句柄
HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
void* pRemoteThread = VirtualAllocEx(hTargetProcess, 0,
dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
//将线程体拷贝到宿主进程中
if (!WriteProcessMemory(hTargetProcess,
pRemoteThread, &threadProc, dwThreadSize, 0)) {
return 0;
}
//定义线程参数结构体变量
RemoteParam remoteData;
//填充结构体变量中的成员
HINSTANCE hUser32 = LoadLibrary("User32.dll");
remoteData.dwMessageBox = (DWORD)GetProcAddress(hUser32, "MessageBoxA");
FreeLibrary(hUser32);
strcat(remoteData.szMsg, "Hello/0");
//为线程参数在宿主进程中开辟存储区域
RemoteParam* pRemoteParam = (RemoteParam*)VirtualAllocEx(
hTargetProcess , 0, sizeof(RemoteParam), MEM_COMMIT, PAGE_READWRITE);
//将线程参数拷贝到宿主进程地址空间中
if (!WriteProcessMemory(hTargetProcess ,
pRemoteParam, &remoteData, sizeof(remoteData), 0)) {
return 0;
}
//在宿主进程中创建线程
HANDLE hRemoteThread = CreateRemoteThread(
hTargetProcess, NULL, 0, (DWORD (__stdcall *)(void *))pRemoteThread,
pRemoteParam, 0, &dwWriteBytes);
CloseHandle(hRemoteThread);
return 0;
}
最后
以上就是怡然楼房为你收集整理的CreateRemoteThread API 函数心得的全部内容,希望文章能够帮你解决CreateRemoteThread API 函数心得所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复