0%

进程自创建

通过父进程创建一个同名的子进程(进程的自创建)

实现

1、获取父进程的模块路径 2、父进程以挂起状态创建子进程(需要注意,因为是父进程实现自我创建,也就是说父进程创建的进程也是他自己,所以当父进程以挂起状态创建子进程的时候,父进程此时本身也是处于挂起状态的) 3、获取此时父进程的进程上下文来当作子进程的上下文 4、设置子进程上下文的Eip/RIp(x64) 5、恢复现场(设置上下文,恢复线程)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<Windows.h>
#include <stdio.h>
#include <tchar.h>
#pragma warning(disable:4996)

void ChildProcess()
{
MessageBoxA(NULL, "子进程创建成功", "子进程创建成功", MB_OK);
Sleep(3000);
printf("This is child process");
ExitProcess(0);
}

void main()
{
TCHAR szPath[MAX_PATH] = { 0, };
STARTUPINFO si = { sizeof(STARTUPINFO), };//STARTUPINFO的第一个元素必须初始化为该结构体的大小
PROCESS_INFORMATION pi = { 0, };
CONTEXT ctx = { 0, };

printf("This is Father Process!\n");

//1.获取父进程模块
if (!GetModuleFileName(NULL, szPath, sizeof(TCHAR) * MAX_PATH))
//当第一个参数为NULL的时候,会返回当前进程的文件路径,第二个参数指向缓冲区,第三个参数指明缓冲区的大小
{
printf("GetModuleFileName() failed! [%d]\n", GetLastError());
return;
}

//2.创建挂起的新进程
//设置使用多字符集 这里主要是使用W版本的 找了半个晚上的错误才发现。。。。
BOOL bRet = CreateProcessW((LPWSTR)szPath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);

if (!bRet) {
printf("CreateProcessW() failed! [%d]\n", GetLastError());
return;
}

//设置线程上下文
ctx.ContextFlags = CONTEXT_FULL;
//3.获取子进程的线程上下文
GetThreadContext(pi.hThread, &ctx);

//4.设置子进程的上下文,将ctx结构体里边的eip选项指向定义的函数(也就是将当前的eip指向子进程,直接执行子进程的函数)
ctx.Eip = (DWORD)ChildProcess;
//如果是x64 则使用Rip
//ctx.Rip = (DWORD64)ChildProcess;
SetThreadContext(pi.hThread, &ctx);

//5.恢复现场
if( FALSE == ResumeThread(pi.hThread)) {
printf("ResumeThread Failed! [%d]\n",GetLastError());
return;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

}

References

https://blog.csdn.net/annhf/article/details/1272601 https://blog.csdn.net/sxr__nc/article/details/106199728

欢迎关注我的其它发布渠道

------------- 💖 🌞 本 文 结 束 😚 感 谢 您 的 阅 读 🌞 💖 -------------