I post my own answer based on my own research. I am not sure about correctness of the parts in bold. Comments correcting my answer or fuller and better answers are welcome. I will edit out the boldness after I receive comments confirming or refuting my assumptions.
Assume that your malicious buffer overwrote the _EXCEPTION_REGISTRATION_RECORD
and you found its offset. Now as a first step of SEH exploitation you need to overwrite the record's second field, PEXCEPTION_ROUTINE
, with address of pop pop ret
instruction sequence. At this point, if you do not try to find this sequence in the .exe module being exploited, it does not matter if it was compiled with /SAFESEH
.
Next, you turn to picking pop pop ret
instruction sequence address from one of DLLs loaded by the vulnerable executable. After you picked that address and overwrote the PEXCEPTION_ROUTINE
field with it, at the time of exception the OS takes that address, determines the .dll module the address belongs to, and if the .dll was compiled with /SAFESEH
, checks if that .dll's module safe exception handler table contains the given address. If the .dll was built with /SAFESEH
and the address you used is not present in the table, the execution flow is not passed to that address and exploitation fails. If the .dll was built without /SAFESEH
, then OS has nothing to check against and this step of the exploitation works.