内核对象


什么是内核对象

像进程、线程、文件、事件等在内核都有一个对应的结构体,这些结构体由内核负责管理。我们管这样的对象叫做内核对象。

如何管理内核对象

访问内核地址错误会直接报成蓝屏

每一个进程都有一个句柄表(防火墙:应用层和内核层隔离开来,避免应用层访问错误)


不是所有的内核对象都有句柄表,而是EPROCESS ,通过句柄值来对内核对象进行操作

多进程共享一个内核对象


其中A的值为2 ,直到A的为0时就销毁了内核对象(除了线程

如何关闭线程内核对象了


如果想要真正的移除一个内核对象,你首先要终止这个线程然后关掉所有句柄的线程

#include "stdafx.h"
#include
/*
创建子进程
返回值:BOOL成功与失效
*/

BOOL CreateChildProcess(PTCHAR szChildProcssName, PTCHAR szCommandLine)
{
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	ZeroMemory(&pi,sizeof(pi));
	ZeroMemory(&si,sizeof(si));
	if(!CreateProcess(
		szChildProcssName,//对象名称
		szCommandLine,//命令行
		NULL,//不继承进程句柄
		NULL,//不继承线程句柄
		FALSE,//不继承句柄
		0,//没有创建标志
		NULL,//使用父进程的环境变量
		NULL,//使用父进程目录作为当前目录,可以自己设置目录
		&si,//STARTUPINFOR结构体详细信息
		&pi//PROCESS_INFORMATION结构体进程信息
	))
	{
	printf("CreateChildProcess Error :%d \n",GetLastError());
	return FALSE;
	}
	//获取进程信息
	SuspendThread(pi.hThread);//挂起
	ResumeThread(pi.hThread);//释放

	//释放句柄
	CloseHandle(pi.hProcess); //将计数器的值减一 ,其中的参数为句柄的值,直到为0时关闭
	CloseHandle(pi.hThread);
	return TRUE;


}
int main(int argc, char* argv[])
{	
	TCHAR szApplicationName[] = TEXT("C:\\Program Files\\Internet Explorer\\iexplore.exe");
	CreateChildProcess(szApplicationName,NULL);

	return 0;
}

OpenProcess

如何判断是否为内核对象

带有这个参数的LPSECURITY_ATTRIBUTES lpThreadAttributes,都为内核对象

typedef struct _SECURITY_ATTRIBUTES {  
DWORD nLength;  
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES,  *PSECURITY_ATTRIBUTES,  *LPSECURITY_ATTRIBUTES;

句柄是否"可以"被继承


CreateEvent(NULL,FALSE,FALSE);//第一个参数是决定是否可以被继承,不希望继承时直接填空,希望继承要创建这个结构体
结构体如下

	SECURITY_ATTRIBUTES  sa;
	ZeroMemory(&sa,sizeof(SECURITY_ATTRIBUTES));
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TURE;

句柄是否"允许"被继承(CreateProcess的第五个参数)