【2020.12.31】创建进程

CreateProcess

BOOL CreateProcessA(
  LPCSTR                lpApplicationName,     //指向一个NULL结尾的、用来指定可执行模块的字符串。
  LPSTR                 lpCommandLine,         //指向一个以NULL结尾的字符串,该字符串指定要执行的命令行。
  LPSECURITY_ATTRIBUTES lpProcessAttributes,   //指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。如果lpProcessAttributes参数为空(NULL),那么句柄不能被继承。
  LPSECURITY_ATTRIBUTES lpThreadAttributes,    //同lpProcessAttribute,不过这个参数决定的是线程是否被继承,通常置为NULL。
  BOOL                  bInheritHandles,       //指示新进程是否从调用进程处继承了句柄。
  DWORD                 dwCreationFlags,       //指定附加的、用来控制优先类和进程的创建的标志。还用来控制新进程的优先类,优先类用来决定此进程的线程调度的优先级。
  LPVOID                lpEnvironment,         //指向一个新进程的环境块。如果此参数为空,新进程使用调用进程的环境。
  LPCSTR                lpCurrentDirectory,    //指向一个以NULL结尾的字符串,这个字符串用来指定子进程的工作路径。这个字符串必须是一个包含驱动器名的绝对路径。如果这个参数为空,新进程将使用与调用进程相同的驱动器和目录。
  LPSTARTUPINFOA        lpStartupInfo,         //指向一个用于决定新进程的主窗体如何显示的STARTUPINFO结构体。
  LPPROCESS_INFORMATION lpProcessInformation   //指向一个用来接收新进程的识别信息的PROCESS_INFORMATION结构体。
);

结构体

STARTUPINFO

进程启动时的相关信息,由父进程填充并传递进来。

typedef struct _STARTUPINFOA {
  DWORD  cb;			//指定该结构大小
  LPSTR  lpReserved;	        //保留, 置为NULL
  LPSTR  lpDesktop;		//指定一个字符串, 包括该进程的桌面名或窗口位置名
  LPSTR  lpTitle;		//指定控制台进程创建的新控制台窗口标题
  DWORD  dwX;			//指定新窗口左上角的X、Y偏移量(像素点)
  DWORD  dwY;
  DWORD  dwXSize;		//指定新窗口的宽度和高度
  DWORD  dwYSize;
  DWORD  dwXCountChars;	        //指定新窗口的屏幕缓冲区的宽度和高度
  DWORD  dwYCountChars;
  DWORD  dwFillAttribute;	//指定新窗口的初始文字和背景颜色
  DWORD  dwFlags;		//创建窗口标志
  WORD   wShowWindow;		//新窗口的显示状态
  WORD   cbReserved2;		//保留, 置为0
  LPBYTE lpReserved2;		//保留, 必须置为NULL
  HANDLE hStdInput;		//指定一个句柄, 该句柄用作进程的标准输入句柄
  HANDLE hStdOutput;		//指定一个句柄, 该句柄用作进程的标准输出句柄
  HANDLE hStdError;		//指定一个句柄, 该句柄用作进程的标准错误句柄
} STARTUPINFOA, *LPSTARTUPINFOA;

PROCESS_INFORMATION

在创建进程时相关的数据结构之一,该结构返回有关新进程及其主线程的信息。

为什么会有线程句柄和线程ID?

进程的创建过程中一定会创建一个线程,所以该结构体中含有线程信息就能理解。

typedef struct _PROCESS_INFORMATION {
  HANDLE hProcess;	//进程句柄
  HANDLE hThread;	//线程句柄
  DWORD  dwProcessId;	//进程ID
  DWORD  dwThreadId;	//线程ID
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;

创建进程例子

创建一个IE浏览器进程,并打开网址。

#include <iostream>
#include <Windows.h>

//创建子进程
BOOL CreateChildProcess(PTCHAR szChildProcessName, PTCHAR szCommandLine)
{
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

        //ZeroMemory:用0来填充一块内存区域
	ZeroMemory(&si, sizeof(si));
	ZeroMemory(&pi, sizeof(pi));

        //设置当前结构体大小
	si.cb = sizeof(si);

	//创建子进程
	if (!CreateProcess(
		szChildProcessName,	//对象名称
		szCommandLine,		//命令行
		NULL,			//不继承进程句柄
		NULL,			//不继承线程句柄
		FALSE,			//不继承句柄
		0,			//没有创建标志
		NULL,			//使用父进程环境变量
		NULL,			//使用父进程目录作为当前目录

                //in参数,需要传递进去给函数使用的。
		&si,			//STARTUPINFO 结构体详细信息

                //out参数,当执行完后通过该指针写结果,相当于返回值。
		&pi			//PROCESS_INFORMATION 结构体进程信息
	))
	{
                //如果创建子进程失败, 使用 GetLastError 查看错误信息。
		printf("CreateChildProcess Error:%d\n", GetLastError());
		return FALSE;
	}
	//释放句柄
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);
	return TRUE;
}

int main(int argc, char* argv[])
{
	TCHAR szApplicationName[] = TEXT("C:\\Program Files\\Internet Explorer\\iexplore.exe");
	TCHAR szCmdline[] = TEXT(" https://blog.csdn.net/qq_18120361");

	CreateChildProcess(szApplicationName, szCmdline);

	return 0;
}

简单反调试例子

  1. 由于 STARTUPINFO 结构体是由被创建的进程的父进程填充并传递过来的。
  2. 所以不同的父进程传递进来的结构体也可能不同。
  3. 可以对该结构体中的内容比较,来判断是否被调试。
#include <iostream>
#include <Windows.h>

void AntiDebug()
{
	//当前进程初始化信息
	//由该进程的父进程传递进来, 不同的父进程传递的结构体内容可能不同
	//可以用于反调试
	STARTUPINFO tmp;

        //获取进程在启动时的 STARTUPINFO 结构体
	GetStartupInfo(&tmp);

	//没有打印结构体中的所有内容
	printf("%x %x %x %x %x %x %x %x\n", tmp.dwX, tmp.dwY, tmp.dwXCountChars, tmp.dwYCountChars, tmp.dwFillAttribute, tmp.dwXSize, tmp.dwYSize, tmp.dwFlags);

	return;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值