Dr7.GD single/multi CPU version by deroko of ARTeam
Dr7.GD single/multi CPU version
Basically whole this project has been started for own needs to stop some silly protections from messing up with drX registers. Only ones allowed to access drX registers are cpthook and NTIce, others are NOT allowed to modify those registers.
This code is designed to work with Sice in paticilar, as there is no real use when it is used without SoftICE.
Saving dr6 is first issue important when writing such code. IA32 manual, newer one, says that certain exceptions may clear B0/B3, that's why those have to be saved whenever int 1 is generated. As each CPU has it's own set of drX registers, that means that for each CPU it's required to keep track of dr6 register. More can be found at woodmann.com and my blog.
Problems with int 01 and int 0d on intel cpu. Well Intel simply treats (at least that's how it looks like at intel cpu on which I've tested this code) GD bit as higher priority then Int 0xD. Seems that intel CPU when detects mov to/from drX first checks for GD bit being set in dr7, and then it checks CPL. This problem is solved by simply redirecting all ring3 drX accesses to int 0d handler. On AMD I didn't see this problem.
MP issue when softice is active. Well SoftICE has to control whole system, so when bpm is set (drX) it will use IPI to set drXes on each CPU. Now comes fun part. By default NMI is setup as TaskGate, when softice is running on single cpu machine it will be setup as IdtGate, on mp machines softice will keep NMI as TaskGate. So, here NT flag will be set in eflags + iretd from handler must no be used, as iretd will "unblock" NMI, also if NT flag is set, iretd will return to interupted task using TSS.BackLink, also bad thing. When drX access occurs from NMI it is required to simply return from interupt using retn.