Instead of using hardware breakpoints and dealing with the complications they cause, how about this? Replace the IMAGE_DIRECTORY_ENTRY_EXPORT on critical DLLs with a pointer to an empty export directory, then patch ntdll!LdrGetProcedureAddress to know where are the real export directories for those critical DLLs.
This would avoid needing hardware breakpoints, allow protecting more than four DLLs, and--as far as I can tell--be no worse with compatibility than the hardware breakpoint solution.
Melissa