句柄表和继承
image句柄代表着备操作的对象
句柄的本质(handler)
句柄表可以看做一个非常大的机构体数组
句柄表的结构
索引值: 进程通过索引找到句柄表中对应的选项
内核对象地址: 通过地址直接找到对应的内核对象
访问掩码: 控制了访问权限
标志位: 标志改句柄能否被继承
句柄表是如何工作的:
每个进程的内核对象,都有一个句柄与之对应
操作对应进程,需要获得进程句柄。通过系统api操作
比如A要操作B进程
A会在A的句柄表中空白的位置存储B的内核地址,返回索引值 就是句柄
当操作B进程的时候 就使用句柄调用系统api操作B进程
类似于的 如果有C、D等进程和A进程一起操作B进程的话,这样一来 C.D自己的句柄表中都会存储B的内核对象地址。这么一来就带来一个问题
如果A C D 同时访问B的资源,突然间B的内核对象被销毁释放了,那么A C D三个都会出错
为了缓解此类错误,windows操作系统使用了内核对象使用计数机制:
内核对象的使用计数:
每一个内核对象都有一个使用计数
的属性
每当内核对象被获得过一次,此内核对象的使用计数就会+1
当其他句柄中此内核对象的句柄销毁时,此内核对象并不会被销毁,而是使用计数-1
当内核对象的使用计数为0 的时候 就说明此时并没有其他地方再使用此内核对象了,此时内核对象就会被销毁
//销毁句柄 内核计数-1
BOOL CloseHandle
(
HANDLE hObject //关闭的目标句柄
)
句柄的继承关系
当父进程创建子进程的时候,父进程标志位为0的,表示此条索引(句柄)不想被子进程继承
image imageBOOL CreateProcess(
LPCTSTR lpApplicationName, // 路径
LPTSTR lpCommandLine, // 命令行
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程安全属性
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程安全属性
BOOL bInheritHandles, // 继承标志位
DWORD dwCreationFlags, // 创建标志
LPVOID lpEnvironment, // 环境块
LPCTSTR lpCurrentDirectory, // 驱动目录
LPSTARTUPINFO lpStartupInfo, // 启动信息
LPPROCESS_INFORMATION lpProcessInformation // 进程信息
);
进程标志位参数 BOOL bInheritHandles
表示了新进程(子进程)是否继承父进程句柄表中的句柄,如果为true,那么就继承父句柄表中可被继承的句柄,并且继承的句柄具有和原始句柄相同的值和访问权限
进程安全属性和线程安全属性 参数,决定是否可以由子进程(线程)继承返回的句柄。如果是NULL 则表示不能被继承
//安全属性
SECURITY_ATTRIBUTE
{
DWORD nLength; //结构体宽度
LPVOID lpSecurityDescriptor;//安全描述符
BOOL bInheritHandle;//被创建的句柄能否被继承
}
//安全描述符:决定了用户的访问权限,可以由他指定哪些用 户可以访问,以及一些访问权限,一般填NULL
//句柄继承选项:决定了被创建的对象的句柄是否是可以被继 承的
网友评论