首页
社区
课程
招聘
[求助]为什么用HANDLE来表示进程ID
发表于: 2013-7-9 19:44 7310

[求助]为什么用HANDLE来表示进程ID

2013-7-9 19:44
7310
在监控进程时,常用PsSetCreateProcessNotifyRoutine注册一个回调函数。
查看回调函数签名:

VOID (*PCREATE_PROCESS_NOTIFY_ROUTINE) (
    IN HANDLE  ParentId,
    IN HANDLE  ProcessId,
    IN BOOLEAN  Create
    );

平时我们用到的进程PID也是DWORD类型(包括64bit系统也应该是DWORD)。
而这里为什么需要HANDLE来表示进程ID (即:IN HANDLE  ProcessId)
在64bit 系统上,DWORD是 32 位无符号整数,而HANDLE 为64位指针。
(1)我想知道微软为什么这么设计(用HANDLE来作为pid类型)
(2)在64bit环境下,如果传入的 DWORD很大 pid 最高位为1:
pid & 0x80000000 == 0x80000000,扩展为64位 HANDLE 会不会把1当作符号位扩展?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 257
活跃值: (67)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
HANDLE只是个数据类型,可以表示指针,也能代表整数
用HANDLE来表示进程ID没什么不可以的,无需咬文嚼字的
2013-7-9 20:31
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
soh
3
这么说也可以,我只是很好奇
2013-7-9 20:38
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
soh
4
不过我还是觉得,同样的对象,在内核态和用户态的表示可能不一样。
同样的进程id,在用户态可能用DWORD,但是在内核可能用HANDLE,我想这里应该是有原因的。
哪怕是历史遗留原因。
2013-7-9 20:50
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
    Windows中使用HANDLE_TABLE来管理进程的资源,比如进程打开了一个文件,就插入到该进程句柄表中,然后把在句柄表中的索引当作本次打开文件的句柄。
   在内核中,windows创建进程后,把进程的EPROCESS插入到一个全局的句柄表中,这个句柄表叫PspCidTable,然后把进程在该句柄表中的索引当作进程ID。由于PspCidTable使用了和资源一模一样的HANDLE_TABLE,所以进程ID其实是进程的句柄。只不过这个ID不在任何进程的句柄表中,所以不能只用直接使用。如果你需要操作进程,拿着这个ID,交给OpenProcess->nt->NtOpenProcess,这个函数会从PspCidTable获取到进程的EPROCESS结构体,然后使用ObOpenObjectByPointer在本进程的句柄表中创建一个指向EPROCESS的句柄,这个时候,你才可以操作进程。
2013-7-9 21:07
0
雪    币: 601
活跃值: (256)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
6
填入的DWORD在进入内核之前被转换为HANDLE了
2013-7-9 21:31
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
soh
7
谢谢你详细的回答,我有两点不是很理解:
(1)你说 IN HANDLE  ProcessId 这个Id 就是进程的句柄,并且是在系统全局句柄表中,不是进程内句柄表。
那么在本进程句柄表中创建的创建的指向EPROCESS的句柄和全局表中的句柄的区别是什么?
(2)这里的ProcessId 和我们在应用层开发时说到的进程ID和进程句柄中的哪个对应?
也就是和PROCESS_INFORMATION结构中的 hProcess对应还是dwProcessId对应,应该是hProcess对么?
2013-7-9 21:56
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
soh
8
就是这个地方填入的其实是从ProcessId转换后的的hProcess值了是么
2013-7-9 21:58
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
soh
9
就是这个地方填入的其实是从ProcessId转换后的的hProcess值了是么
2013-7-9 21:59
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
Pid.Tid是EPROCESS.ETHREAD在PspCidTable中的索引值
进程内的句柄是对象头在本进程的进程句柄表中的索引.
内核句柄是对象头在System进程句柄表中的索引+0x800000000
搞不清楚具体是什么可以自己去解析看句柄指向的对象是否正确就可以了.....
以上所说如有问题欢迎指正...
2013-7-9 22:26
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
1、没有区别,只不过位于不同的句柄表而已。
2、驱动里的HANDLE ProcessId,跟应用层的DWORD ProcessId是对应的。
3、以上的统一解释就是因为例如TerminateProcess等进程操作函数,里边使用到的hProcess,传到内核后,内核使用了本进程的句柄表转换为EPROCESS,所以你必须通过OpenProcess去打开,这样你传入的ProcessId(PspCidTable)才会被转换到本进程的句柄表,然后返回给你个hProcess。其实ProcessId和hProcess都是进程的句柄,只不过由于位于不同的句柄表,而微软的进程操作函数只是过了本进程的句柄表,所以需要拿着全局的句柄ProcessId转换为本进程的句柄hProcess。
4、如果你了解DuplicateHandle的话,我想你就能明白上面的意思了,PspCidTable可以认为是SYSTEM进程的句柄表(举例而已,因为SYSTEM也有自己的句柄表),每一个进程在SYSTEM中都有一个句柄,你枚举进程拿到的进程ID,就是SYSTEM里的进程句柄,虽然是进程句柄,你依然不能TerminateProcess去使用,因为不是你进程的句柄,你还是必须用DuplicateHandle转到本进程的句柄表中,并获得一个句柄hProcess,才能操作对应的进程。当然这个只是比如而已,但基本是这个道理。
2013-7-9 22:27
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
HANDLE 是*void,DWORD是unsigned long,这两种类型有符号位的么?没有符号位你担心什么扩展问题?多注意下基础知识
2013-7-9 22:40
0
雪    币: 39
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
soh
13
非常感谢
2013-7-9 23:11
0
游客
登录 | 注册 方可回帖
返回
//