Win32创建远程线程
0x00 相关介绍:
Windows系统的进程拥有独立的虚拟地址空间
进程之间的虚拟地址空间互不干扰
在应用层,进程A可以通过WIN32API CreateRemoteThread 在进程B的虚拟地址空间中创建一个线程并且执行
0x01 核心API说明:
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 );
参数说明:
1、 hProcess:进程句柄,目标进程(进程B)的句柄
2、 lpThreadAttributes:安全描述符的结构体指针,填 NULL 即可
3、 dwStackSize:要创建的远程线程的堆栈大小,一般填 0 使用默认大小
4、 lpStartAddress:远程线程的执行体,也就是创建的线程要执行的过程函数
5、 lpParameter:远程线程执行体的参数,与参数4配合使用
6、 dwCreationFlags:创建标志,一般填0
7、 lpThreadId:线程ID的指针,用于接收远程线程创建成功后的ID
返回值:
线程句柄
0x02 目标程序:
用于测试的目标进程代码如下:
#include <windows.h>
#include <stdio.h>void Fun(void)
{
for(size_t i = 0; i < 10; i++)
printf("%s addr:0x%p\r\n", __FUNCTION__, Fun);
}int main(int argc, char* argv[])
{
Fun();
//MessageBox(NULL, TEXT("执行完成!"), TEXT("提示"), MB_OK);getchar();
return 0;
}
编译生成 Project1.exe
0x03 远程调用程序:
在远程调用程序中实现:在Project1.exe创建一个线程并调用Fun()
首先运行 Project1.exe 查看 Fun() 的地址:
得到目标函数地址:0x00A1F521
编写远程调用程序:
#include <windows.h>
#include "Process.h"#define NAME L"Project1.exe"
#define FUN_ADDR 0x00A1F521int main(int argc, char* argv[])
{
Process* pProcess = new Process(NAME, FALSE);
if(pProcess->hProcess == NULL){
OutputDebugString(TEXT("未找到目标进程!\r\n"));
exit(-1);
}
//OutputDebugString(TEXT("已找到目标进程!\r\n"));
HANDLE hThread = CreateRemoteThread(pProcess->hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)FUN_ADDR,
NULL, 0, NULL);
if (hThread == NULL) {
delete pProcess;
OutputDebugString(TEXT("CreateRemoteThread 失败!\r\n"));
exit(-1);
}
CloseHandle(hThread);delete pProcess;
return 0;
}#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )
其中 Process 类的相关内容参考:https://www.cnblogs.com/DarkBright/p/10809092.html
最后一行:#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" ) 表示隐藏控制台
编译执行:
Project1.exe 中的 Fun() 被再次执行