内核对象和句柄
2017-03-05 22:50
225 查看
内核对象的数据结构只能由操作系统的内核访问,所以应用程序不能再内存中定位这些数据结构并直接修改其内容。
可以利用windows的api函数进行操作。当调用一个会创建内核对象的函数后,会返回一个句柄,它标识了所创建的对象。
这些句柄值是与进程相关的,如果传递给其他进程,可能会失败,因为每个进程会有一个句柄表,所以使用的时候可能是完全不用的内核对象。
内核对象的所有者是操作系统,当进程创建一个内核对象,然后进程终止,则内核对象并不一定销毁。
大多数情况下,这内核对象是会销毁的,但是假如另外一个进程也在使用我们进程创建的内核对象,那么在其他进程使用完他之前,他是不会销毁的。
操作系统内核知道有多少进程正在使用一个特定的内核对象,因为每个对象都包含了一个使用计数!,只有当使用计数为0,操作系统才会销毁这内核对象。
用于插件内核对象的所有函数基本都有一个指向SECURITY_ATTRIBUTES结构的指针作为参数,一般都是传入NULL,这样创建的内核对象具有默认的安全性,要取决于当前进程的安全令牌。
一个进程在初始化时,系统将会为他分配一个句柄表,这句柄表供内核对象使用,不适用于用户对象和GDI对象。
用于插件内核对象的函数都会返回一个与进程相关的句柄,系统用所以来表示内核对象的信息保存在进程句柄表中的具体位置。
无论以什么方式创建内核对象,我们都需要调用closehandle来关闭内核对象。这时候会通过句柄值找到内核对象的数据结构的地址,减少结构中的使用计数,如果使用计数为0,则销毁内核对象。
跨进程边界共享内核对象 三种方法
使用对象句柄继承:只有在一个父子关系的时候才可以使用,当父进程创建一个内核对象,父进程必须向系统指出它希望这对象的句柄是可以继承的。
为了插件一个可继承的句柄,父进程必须分配并初始化一个SECURITY_ATTRIBUTES,将bInheritHandle设置为true,这时候创建出来的对象在句柄表中的标志就是可继承的。
下一步是父进程生成子进程,
其中的bInheritHandles设置为true,这样子进程就会继承父进程的可继承的句柄的值。系统会遍历父进程的句柄表,对他的每个记录项进行检查,凡是包含一个有效的可继承的标识,,都会被完整的复制到子进程的句柄表。除了复制句柄表的记录项,系统还会递增内核对象的使用计数。对于32bit系统,内核地址在0x80000000到0xffffffff,对于64bit的系统则是0x000004000 00000000 到0xffffffff ffffffff。
改变句柄的标志
第一个参数hObject标识了一个有效句柄。
第二个参数dwMask告诉函数我们想更改哪个或者哪些标志:
1\ HANDLE_FLAG_INHERIT 用CreateProcess(bInheritHandle设为TRUE)创建出来的子进程可以继承对象句柄
2\HANDLE_FLAG_PROTECT_FROM_CLOSE 无法调用CloseHandle关闭对象句柄
第三个参数dwFlags指出希望把标志设为什么。
跨进程共享内核对象的第二个方法就是为对象命名,不过不怎么推介。
第三种就是复制对象句柄,这应该是比较常见的。
hSourceProcessHandle:源进程内核句柄(即负责传递内核对象句柄的进程句柄)
hSourceHandle:要传递的内核对象句柄
hTargetProcessHandle:目标进程内核句柄
lpTargetHandle:接收内核对象句柄的地址
dwDesiredAccess:TargetHandle句柄使用何种访问掩码(这个掩码是在句柄表中的一项)
bInheritHandle:是否拥有继承
dwOptions:当设DUPLICATE_SAME_ACCESS时,表示目标句柄拥有和源进程的句柄一样的访问掩码,如果设置次参数,会忽略dwDesiredAccess。
当设DUPLICATE_CLOSE_SOURCE时,传输完后,关闭源中的内核对象句柄。
可以利用windows的api函数进行操作。当调用一个会创建内核对象的函数后,会返回一个句柄,它标识了所创建的对象。
这些句柄值是与进程相关的,如果传递给其他进程,可能会失败,因为每个进程会有一个句柄表,所以使用的时候可能是完全不用的内核对象。
内核对象的所有者是操作系统,当进程创建一个内核对象,然后进程终止,则内核对象并不一定销毁。
大多数情况下,这内核对象是会销毁的,但是假如另外一个进程也在使用我们进程创建的内核对象,那么在其他进程使用完他之前,他是不会销毁的。
操作系统内核知道有多少进程正在使用一个特定的内核对象,因为每个对象都包含了一个使用计数!,只有当使用计数为0,操作系统才会销毁这内核对象。
用于插件内核对象的所有函数基本都有一个指向SECURITY_ATTRIBUTES结构的指针作为参数,一般都是传入NULL,这样创建的内核对象具有默认的安全性,要取决于当前进程的安全令牌。
typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; / /结构体的大小,可用SIZEOF取得 LPVOID lpSecurityDescriptor; / /安全描述符 BOOL bInheritHandle ;/ /安全描述的对象能否被新创建的进程继承 } SECURITY_ATTRIBUTES,* PSECURITY_ATTRIBUTES;
一个进程在初始化时,系统将会为他分配一个句柄表,这句柄表供内核对象使用,不适用于用户对象和GDI对象。
用于插件内核对象的函数都会返回一个与进程相关的句柄,系统用所以来表示内核对象的信息保存在进程句柄表中的具体位置。
无论以什么方式创建内核对象,我们都需要调用closehandle来关闭内核对象。这时候会通过句柄值找到内核对象的数据结构的地址,减少结构中的使用计数,如果使用计数为0,则销毁内核对象。
跨进程边界共享内核对象 三种方法
使用对象句柄继承:只有在一个父子关系的时候才可以使用,当父进程创建一个内核对象,父进程必须向系统指出它希望这对象的句柄是可以继承的。
为了插件一个可继承的句柄,父进程必须分配并初始化一个SECURITY_ATTRIBUTES,将bInheritHandle设置为true,这时候创建出来的对象在句柄表中的标志就是可继承的。
下一步是父进程生成子进程,
BOOL CreateProcess ( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATIONlpProcessInformation );
其中的bInheritHandles设置为true,这样子进程就会继承父进程的可继承的句柄的值。系统会遍历父进程的句柄表,对他的每个记录项进行检查,凡是包含一个有效的可继承的标识,,都会被完整的复制到子进程的句柄表。除了复制句柄表的记录项,系统还会递增内核对象的使用计数。对于32bit系统,内核地址在0x80000000到0xffffffff,对于64bit的系统则是0x000004000 00000000 到0xffffffff ffffffff。
改变句柄的标志
BOOL WINAPI SetHandleInformation( _In_ HANDLE hObject, _In_ DWORD dwMask, _In_ DWORD dwFlags );
第一个参数hObject标识了一个有效句柄。
第二个参数dwMask告诉函数我们想更改哪个或者哪些标志:
1\ HANDLE_FLAG_INHERIT 用CreateProcess(bInheritHandle设为TRUE)创建出来的子进程可以继承对象句柄
2\HANDLE_FLAG_PROTECT_FROM_CLOSE 无法调用CloseHandle关闭对象句柄
第三个参数dwFlags指出希望把标志设为什么。
跨进程共享内核对象的第二个方法就是为对象命名,不过不怎么推介。
第三种就是复制对象句柄,这应该是比较常见的。
BOOL WINAPI DuplicateHandle( __in HANDLE hSourceProcessHandle, __in HANDLE hSourceHandle, __in HANDLE hTargetProcessHandle, __out LPHANDLE lpTargetHandle, __in DWORD dwDesiredAccess, __in BOOL bInheritHandle, __in DWORD dwOptions );
hSourceProcessHandle:源进程内核句柄(即负责传递内核对象句柄的进程句柄)
hSourceHandle:要传递的内核对象句柄
hTargetProcessHandle:目标进程内核句柄
lpTargetHandle:接收内核对象句柄的地址
dwDesiredAccess:TargetHandle句柄使用何种访问掩码(这个掩码是在句柄表中的一项)
bInheritHandle:是否拥有继承
dwOptions:当设DUPLICATE_SAME_ACCESS时,表示目标句柄拥有和源进程的句柄一样的访问掩码,如果设置次参数,会忽略dwDesiredAccess。
当设DUPLICATE_CLOSE_SOURCE时,传输完后,关闭源中的内核对象句柄。
//ALL of the following code is executed by Process S. //Createamutex object accessible by Process S. HANDLE hObjProcessS = CreateMutex(NULL, FALSE, NULL); //Open ahandle to Process T's kernel object. HANDLE hProcessT = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessIdT); //Anuninitilized handle relative to Process T. HANDLE hObjProcessT; //GiveProcess T accesss to our mutex object DuplicateHandle(GetCurrentProcess(), hObjProcessS, hProcessT, &hObjProcessT, 0, FALSE, DUPLICATE_SAME_ACCESS); //Usesome IPC mechanism to get the handle //valuein hOnjProcess S into Process T //We nolonger need to communicate with Process T. CloseHandle(hProcessT); //WhenProcess S no longer needs to Use the mutex, //itshould close it. CloseHandle(hObjProcessS);
相关文章推荐
- 枚举指定进程内核对象句柄的C源代码
- 读书笔记----《windows核心编程》第三章 内核对象1(句柄与安全性)
- windows编程(1)-句柄,内核对象
- windows笔记-进程的内核对象句柄表
- 白话windows内核对象共享之复制对象句柄
- windows核心编程--内核对象和句柄泄漏
- Windows内核对象(1) -- 内核对象与句柄
- 内核对象及句柄的本质区别
- windows笔记-跨越进程边界共享内核对象【对象句柄的继承性】
- windows笔记-跨越进程边界共享内核对象【对象句柄的继承性】
- windows笔记-跨越进程边界共享内核对象【复制对象句柄】
- windows核心编程--内核对象和句柄泄漏
- 《windows核心编程系列》三谈谈内核对象及句柄的本质
- windows程序设计的一些基础知识点——内核对象以及它们的句柄
- 内核对象与句柄
- 《windows核心编程系列》三谈谈内核对象及句柄的本质
- 跨越进程边界共享内核对象【复制对象句柄】
- windows笔记-跨越进程边界共享内核对象【复制对象句柄】
- 进程的内核对象句柄表
- -跨越进程边界共享内核对象【复制对象句柄】