3) 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 ); } /* end of RtlGetProcessHeaps */ --------------------------------------------------------------------------