windows核心编程笔记-进程

1.CreateProcess的第二参数如果是Unicode版本直接传入字符串常量会造成异常,因为CreateProcess会修改传递的命令行参数,如果传入的是ANSI版本,则不会,因为ANSI版本会先转换为UNICODE这会创建一个临时的副本,所以能够修改。

2.CreateProcess的命令行参数的命令行参数如果没有指定绝对路径就会按照一下顺序搜索可执行文件:

    主进程.exe所在目录 ---> 主进程的当前目录(GetCurrentDirectory所在目录) ---> Windows系统目录,System32文件夹 ---> Windows目录 ---> PATH环境变量中的目录。

3.在CreateProcess时候可以指定LPSTARTUPINFOA结构为StartupInfoEx,并且指定dwCreateFlags为EXTENDED_STARTUPINFO_PRESENT,然后修改StartupInfoEx的lpAttributeList,这个结构体指针要用两次InitializeProcThreadAttributeList,第一次获取结构体大小,然后在堆上分配空间后再调用一次,初始化后调用UpdateProcThreadAttribute将第三个参数设置为PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,第四个设置为要设置的父进程句柄,这样就可以更改CreateProcess创建的进程的父进程信息了。代码如下:

#include<windows.h>
#include<TlHelp32.h>
#include<stdio.h>

DWORD GetProcessIDFromName(char *lpName)
{
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (INVALID_HANDLE_VALUE == hSnapshot)
	{
		return 0;
	}
	PROCESSENTRY32 pe = { sizeof(pe) };
	Process32First(hSnapshot, &pe);
	do
	{
		if (strcmp(pe.szExeFile, lpName) == 0)
		{
			CloseHandle(hSnapshot);
			return pe.th32ProcessID;
		}
	} while (Process32Next(hSnapshot, &pe));
	CloseHandle(hSnapshot);
	return 0;
}

void main()
{
	/* 根据进程名获取任意进程Id */
	DWORD  pid = GetProcessIDFromName("PE_PEEK.exe");//遍历进程快照获取进程ID

													  /* 已全部权限打开services.exe 进程 */
	HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
	if (handle == NULL)
		printf("err processhandle");

	/* 创建启动信息结构体 */
	STARTUPINFOEXA si;

	/* 初始化结构体 */
	ZeroMemory(&si, sizeof(si));

	/* 设置结构体成员 */
	si.StartupInfo.cb = sizeof(si);

	SIZE_T lpsize = 0;

	/* 用微软规定的特定的函数初始化结构体 */
	InitializeProcThreadAttributeList(NULL, 1, 0, &lpsize);

	/* 转换指针到正确类型 */
	char * temp = new char[lpsize];
	LPPROC_THREAD_ATTRIBUTE_LIST AttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)temp;

	/* 真正为结构体初始化属性参数 */
	InitializeProcThreadAttributeList(AttributeList, 1, 0, &lpsize);

	/* 用已构造的属性结构体更新属性表 */
	if (!UpdateProcThreadAttribute(AttributeList, 0,
		PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &handle, sizeof(HANDLE), NULL, NULL))
	{
		return;
	}

	/* 移交指针,这里已更换了父进程的属性表是  */
	si.lpAttributeList = AttributeList;
	char lpExePath[] = "C:\\Users\\Administrator\\Desktop\\MD5.exe";
	//
	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));
	if (CreateProcessA(lpExePath,NULL,NULL,NULL,FALSE,EXTENDED_STARTUPINFO_PRESENT,NULL, NULL, (LPSTARTUPINFOA)&si, &pi))
	{
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);

		/* 收尾处理 */
		DeleteProcThreadAttributeList(AttributeList);
		delete temp;

		return ;
	}
	printf("%d", GetLastError());
	/* 收尾处理 */
	DeleteProcThreadAttributeList(AttributeList);
	delete temp;
	getchar();
	return;
}

4.ExitProcess终止进程不会清理任何C\C++的运行时资源。




猜你喜欢

转载自blog.csdn.net/a893574301/article/details/80709134