This is an issue with ROP as RSP after a syscall contains a usermode address. Interfacing with this usermode stack in any way will cause a fault. However, you can essentially disable SMAP from usermode. There is a bit in the RFLAGS register which can be set to nullify SMAP. The instruction to set this bit is called `STAC` (Set AC Flag in EFLAGS Register). However this instruction is privilaged and will throw a #UD. However as @drew pointed out, you can `POPFQ` an RFLAGS value with that bit set and the CPU will not throw any exceptions. I assumed that since `STAC` cannot be used in usermode, that `POPFQ` would also throw an exception, however this is not the case... Again thank you @drew, without this key information the project would have been a complete mess as there are no useable `mov cr4, [non rax registers] ; ret` gadgets which exist across windows versions.
This is an issue with ROP as RSP after a syscall contains a usermode address. Interfacing with this usermode stack in any way will cause a fault. However, you can essentially disable SMAP from usermode. There is a bit in the RFLAGS register which can be set to nullify SMAP. The instruction to set this bit is called `STAC` (Set AC Flag in EFLAGS Register). However this instruction is privilaged and will throw a #UD. However as @drew pointed out, you can `POPFQ` an RFLAGS value with that bit set and the CPU will not throw any exceptions. I assumed that since `STAC` cannot be used in usermode, that `POPFQ` would also throw an exception, however this is not the case... Again thank you @drew, without this key information the project would have been a complete mess as there are no useable `mov cr4, [non rax registers] ; ret` gadgets which exist across windows versions.
```nasm
```nasm
pushfq ; thank you drew :)
pushfq ; thank you drew :)
pop rax ; this will set the AC flag in RFLAGS which "disables SMAP"...
pop rax ; this will set the AC flag in RFLAGS which "disables SMAP"...
or rax, 040000h;
or rax, 040000h;
push rax ;
push rax ;
popfq;
popfq;
```
```
RFLAGS is restored after the syscall instruction. The original RFLAGS value is pushed onto the stack prior to all of the gadgets and other values.
RFLAGS is restored after the syscall instruction. The original RFLAGS value is pushed onto the stack prior to all of the gadgets and other values.