- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
昨天为了这个破API蓝屏了一整天,估计达20次以上,特此纪念之。
调试定位的过程极其痛苦,不过今天早上终于搞定,简单说说吧。调用完PsLookupProcessByProcessId之后记住要调用ObDereferenceObject,否则Object还会在内存中不被释放,进而导致调用这个API的进程在“退出”后,会有两种状态:在User层的状态是退出了,但在Kernel层的状态还是deleting(用softice的proc命令可以看到),这样当下次再访问这个进程的内存的时候就会蓝屏。奇怪的是在WinXP下才会这样,Win2000中貌似没事,不知道是巧合还是操作系统做了点什么手脚?(这也从另一个侧面反映出Win2000其实不够健壮),懒得细究了,反正弄清楚了也没法维护世界的和平。
源码之前,了无秘密。(private\ntos\ps\pscid.c)
NTSTATUS
PsLookupProcessByProcessId(
IN HANDLE ProcessId,
OUT PEPROCESS *Process
)
/*++
Routine Description:
This function accepts the process id of a process and returns a
referenced pointer to the process.
Arguments:
ProcessId - Specifies the Process ID of the process.
Process - Returns a referenced pointer to the process specified by the
process id.
Return Value:
STATUS_SUCCESS - A process was located based on the contents of
the process id.
STATUS_INVALID_PARAMETER - The process was not found.
--*/
{
PHANDLE_TABLE_ENTRY CidEntry;
PEPROCESS lProcess;
NTSTATUS Status;
CidEntry = ExMapHandleToPointer(PspCidTable, ProcessId);
Status = STATUS_INVALID_PARAMETER;
if (CidEntry != NULL) {
lProcess = (PEPROCESS)CidEntry->Object;
if (lProcess != (PEPROCESS)PSP_INVALID_ID && lProcess->Pcb.Header.Type == ProcessObject && lProcess->GrantedAccess ) {
ObReferenceObject(lProcess);
*Process = lProcess;
Status = STATUS_SUCCESS;
}
ExUnlockHandleTableEntry(PspCidTable, CidEntry);
}
return Status;
}
是由代码中的这行: ObReferenceObject(lProcess); 导致的。 |
|