【Win32】进程以及句柄

注意:本文为学习win32时所写,如有错漏,烦请指出,万分感谢

1、线程与进程是什么

        ①进程:所谓进程,是一个空间的概念,里面装的就是代码执行时所有所需要的资源

        ②线程:所谓线程,是一个动态的概念,简单来说就是跑起来的代码

        所以,一个进程至少要有一个线程才是有意义的

2、进程如何创建的

分区:

空指针赋值区:        0x00000000~0x0000FFFF

用户模式区:            0x00010000~07FFEFFFF

64KB禁入区:          0x7FFF0000~0x7FFFFFFF

内核:                       0x80000000~0xFFFFFFFF

我们点击的程序一般是由explorer.exe调用CreateProcess()创建的,过程如下

        ①、映射exe文件(将exe文件放到自己的内存)

        ②、创建内核对象EPROCESS在高2G

        ③、映射DLL文件(ntdll)

        ④、创建线程内核对象

        ⑤、系统启动线程(先映射DLL,再执行)

3、句柄是什么

        我们知道,在windows上面,进程的低2G是属于自己的,高2G是属于内核的,是所有进程共享的,那么,每个进程在创建时,包括其中的线程,事件等创建时,都会建立一个内核对象在高2G,如果这时候我们要操作这些内核对象,直接将地址给进程的话,一旦地址出错,就会引发很严重的问题

        所以,Windows的解决方案是成立一个句柄表,而内核对象的地址就存在句柄表中,我们要操作这些内核对象,就是要操作这些句柄

        句柄表可以理解为有三列,其中第一列代表的是句柄能否被继承,第二列是句柄的ID,第三列就是句柄所对应的内核对象的地址

以下是学习时所写的代码

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

DWORD CreateChildProcess(PTCHAR szChildProcssName, PTCHAR szCommandLine) {
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	/*
	CreateProcess(
		LPCTSTR lpApplicationName,								//对象名称
		LPTSTR lpCommandLine,									//命令行参数
		LPSECURITY_ATTRIBUTES lpProcessAttributes,				//不允许自己的进程句柄被继承
		LPSECURITY_ATTRIBUTES lpThreadAttributes,				//不允许自己的线程句柄被继承
		BOOL bInheritHandles,									//不继承父进程可继承的句柄
		DWORD dwCreationFlags,									//没有创建标识
		LPVOID lpEnvironment,									//使用父进程环境变量
		LPCTSTR lpCurrentDirectory,								//使用父进程目录作为当前目录
		LPSTARTUPINFO lpStartupInfo,							//STARTUPINFO结构体详细信息
		LPPROCESS_INFORMATION lpProcessInformation				//PROCESS_INFORMATION结构体进程信息
	)
	DWORD dwCreationFlags:
	CREATE_NEW_CONSOLE	//创建新的控制台
	CREATE_SUSPENDED	//挂起的形式创建
	*/
	if (!CreateProcess(
		szChildProcssName,		//对象名称
		szCommandLine,			//命令行参数
		NULL,					//不允许自己的进程句柄被继承
		NULL,					//不允许自己的线程句柄被继承
		FALSE,					//不继承父进程可继承的句柄
		CREATE_NEW_CONSOLE,						//没有创建标识
		NULL,					//使用父进程环境变量
		NULL,					//使用父进程目录作为当前目录
		&si,					//STARTUPINFO结构体详细信息
		&pi						//PROCESS_INFORMATION结构体进程信息
	)) {
		printf("CreateChildProcess Error:%d\n", GetLastError());
		return FALSE;
	}
	printf("ProcessId=%x\nThreadId=%x\nProcessHandle=%x\nThreadHandle=%x\n", pi.dwProcessId, pi.dwThreadId, pi.hProcess, pi.hThread);
	SuspendThread(pi.hThread);	//挂起线程
	for(int i=0; i<10; i++){
		Sleep(500);
		printf("========\n");
	}
	char filePath[100];
	GetModuleFileName(NULL, filePath, 100);
	char workPath[100];
	GetCurrentDirectory(100, workPath);

	printf("模块路径:%s\n工作路径:%s\n", filePath, workPath);

	ResumeThread(pi.hThread);	//释放线程
	

	
	//释放句柄
	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);

	return pi.dwProcessId;
}

int main(int argc, char* argv[])
{
	/*
	CHAR------>char
	WCHAR----->wchar_t------->unsigned short
	TCHAR----->一种宏,随着程序改变编码
	PSTR------>char*
	PWSTR----->WCHAR*
	PTSTR----->一种宏,随着程序改变编码
	*/
	/*
	int MessageBox(
		窗口
		HWND hWnd,
		LPCTSTR TEXT,
		LPCTSTR TITLE,
		UINT uType,//窗口类型
		)
	*/
	/*
	TCHAR title[]=TEXT("title");
	TCHAR text[]=TEXT("text");
	MessageBox(0,text,title,MB_OK);
	*/
	/*
	CreateEvent(
		LPSECURITY_ATTRIBUTES,	//安全描述符,不希望被继承填NULL,希望则要创建如下结构体
		BOOL,					//	
		BOOL,					//
		LPCTSTR,				//对象名称
		)

	SECURITY_ATTRIBUTES sa,
	ZeroMemory(&sa,sizeof(SECURITY_ATTRIBUTES));
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;		//希望被继承
	CreateEvent(sa,FALSE,FALSE);
	*/

	/*
	TerminateProcess(			//终止一个其他进程
		HANDLE hprocess,		//进程句柄
		UINT uExitCode,			//退出码,可以通过GetExitCodeProcess()查询到
		)
	OpenProcess(
		Dword dwDesiredAccess,	//希望拥有什么样的权力,具体查表
		BOOL bInheritHandle,	//是否允许子进程继承
		DWORD deProcessId		//进程PID
		)
	HANDLE hProcess;

	hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,0xECO);

	if(!TerminateProcess(hprocess,1))
	{
	printf("fail to stop the process:%d\n", GetLastError()); 
	}

	*/
	TCHAR szChildProcssName[] = TEXT("G://code/11.27/Debug/11.27.exe");
	TCHAR szCommandLine[] = TEXT("1");
	DWORD processid = CreateChildProcess(szChildProcssName, NULL);
	
	/*
	DWORD GetModuleFileName(  //模块路径(自己在的地方)
		HMODULE hModule,    // 模块的句柄
		LPTSTR lpFilename,  // 模块的文件名(out)
		DWORD nSize         // 缓冲区的大小(in)
	);
	*/
	char filePath[100];
	GetModuleFileName(NULL, filePath, 100);

	/*
	DWORD GetCurrentDirectory(  //工作目录(父进程的地方)
		DWORD nBufferLength,  // 缓冲区大小
		LPTSTR lpBuffer       // 缓冲区指针(out)
	);
	*/

	char workPath[100];
	int i = 100;
	GetCurrentDirectory(100, workPath);

	printf("模块路径:%s\n工作路径:%s\n", filePath, workPath);
	
	//getchar();
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值