BOOLEAN RtlIsValidHandler(IN PEXCEPTION_ROUTINE Handler)
{
	PULONG FunctionTable;
	ULONG FunctionTableLength;
	PVOID Base;
	MEMORY_BASIC_INFORMATION MemInfo;
	ULONG ReturnLengthMemoryInfo, ReturnLengthProcessInfo;
  PEXCEPTION_ROUTINE FunctionEntry;
 	LONG High, Middle, Low;

	//
	// Renvoie la base de la table des SafeSeh, NULL sinon
	//
  FunctionTable=RtlLookupFunctionTable(Handler, &Base, &FunctionTableLength);
  
  //
  // Pas de table SafeSeh
  //
  if(!FunctionTable || !FunctionTableLength)
  {
		if(!NT_SUCCESS(NtQueryVirtualMemory(GetCurrentProcess(), LocalHandler, MemoryBasicInformation, &MemInfo, sizeof(MemInfo), &ReturnLengthMemoryInfo)))
			return true;
		
		//
		// Si la page est exécutable
		//
		if((UCHAR)MemInfo.Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY))
		{
			//
			// Si c'est un module
			//
			if (MemInfo.Type==MEM_IMAGE)
			{
				//
				// Récupère un pointeur sur la liste des SafeSeh
				//
				//
				RtlCaptureImageExceptionValues(MemInfo.AllocationBase, &FunctionTable, &FunctionTableLength);
				if (FunctionTable)
				{
					//
					// Taille de la table nulle ?
					//
					if ( FunctionTableLength )
					return false;
				}
			}
			else
				//
				// La page est exécutable mais n'appartient à aucun module
				//
				return true;
		}
		else
		{
			//
			// La page n'est pas exécutable
			//
			ProcessExecuteFlags = 0;
			
			//
			// Regarde si le DEP est activé sur le process
			//
			if (!NT_SUCESS(ZwQueryInformationProcess(GetCurrentProcess(), ProcessExecuteFlags, &ProcessInformation, sizeof(ProcessInformation), NULL)) || !(ReturnLengthProcessInfo & MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE))
			{
			v10 = -2;
			v9 = -2;
			goto InvalidHandler;
			}
		}
  }
  
  //
  // Pas de SafeSeh
  //
  if((FunctionTable == -1) && (FunctionTableLength == -1))
    return false;
  
  
 
	// Bias the handler value down by the image base and see if the result
	// is in the table
	
	(ULONG)Handler -= (ULONG)Base;
	Low=0;
	High=FunctionTableLength;
	while(High>=Low)
	{
		Middle = (Low + High) >> 1;
		FunctionEntry = (PEXCEPTION_ROUTINE)FunctionTable[Middle];
		if(Handler<FunctionEntry)
		{
			High = Middle - 1;
		} 
		else if(Handler > FunctionEntry)
		{
					Low = Middle + 1;
		}
		else 
		{
			// found it
			return TRUE;
		}
	}
	
InvalidHandler:
  	// Didn't find it
	RtlInvalidHandlerDetected((PVOID)((ULONG)Handler+(ULONG)Base), FunctionTable, FunctionTableLength);
  return 0;
}

