- ntdll!RtlGetProcessHeaps()
Hume(冷雨飘心)果然对SEH了解深入,以前我一直没有关注过__finally块,直到看见 Hume所给的RtlGetProcessHeaps()伪代码,奇怪Hume凭什么认为这里是__finally块, 而不是__except块,仔细研究了一番,佩服Hume!
原C风格的伪代码基本正确,但在表述__finally块范围时有误,另一处是返回值表述 有误,我修正如下,算是狗尾续貂:
/*
- Create: Hume 2003-11-07 17:29
- Modify: scz 2003-11-10 13:51
-
2003-12-01 11:09
- ntdll.dll中定义的全局变量 */ extern unsigned char RtlpDebugPageHeap; extern RTL_CRITICAL_SECTION RtlpProcessHeapsListLock;
DWORD __stdcall RtlGetProcessHeaps ( DWORD NumberOfHeaps, // maximum number of heap handles PHANDLE ProcessHeaps // buffer for heap handles ) { DWORD PebNumberOfHeaps; DWORD LocalNumberOfHeaps; PTEB Teb = NtCurrentTeb(); DWORD ret;
RtlEnterCriticalSection( &RtlpProcessHeapsListLock );
__try
{
PebNumberOfHeaps = Teb->Peb->NumberOfHeaps;
if ( Teb->Peb->NumberOfHeaps > NumberOfHeaps )
{
LocalNumberOfHeaps = NumberOfHeaps;
}
else
{
LocalNumberOfHeaps = Teb->Peb->NumberOfHeaps;
}
/*
* 这条语句可能引发异常,需要SEH机制的保护
*/
CopyMemory
(
ProcessHeaps,
Teb->Peb->ProcessHeaps,
LocalNumberOfHeaps * sizeof( HANDLE )
);
/*
* 修正形参,为处理调试堆做准备
*/
ProcessHeaps += LocalNumberOfHeaps * sizeof( HANDLE );
NumberOfHeaps -= LocalNumberOfHeaps;
}
__finally
{
ret = PebNumberOfHeaps;
RtlLeaveCriticalSection( &RtlpProcessHeapsListLock );
}
/*
* 注意,后续代码不受本函数中的SEH机制保护,并且已经离开临界区。
* RtlpDebugPageHeapGetProcessHeaps()有自己的SEH机制提供保护。
*/
if ( RtlpDebugPageHeap )
{
ret += RtlpDebugPageHeapGetProcessHeaps
(
NumberOfHeaps,
ProcessHeaps
);
}
/*
* The return value is the number of heap handles that are valid for
* the calling process.
*
* 注意,这个返回值不是当前获取的堆句柄数,而是整个进程中有效堆句柄数。
*/
return( ret );