diff --git a/assembly/x64/assembly.asm b/assembly/x64/assembly.asm index 5b5294c..a175ae5 100755 --- a/assembly/x64/assembly.asm +++ b/assembly/x64/assembly.asm @@ -626,11 +626,14 @@ __asm_fastop proc frame mov rdx, qword ptr CXT_TO_SRC[r8] mov rcx, qword ptr CXT_TO_SRC2[r8] + ; save host eflags + pushfq push qword ptr[rdi] popfq call rsi pushfq pop qword ptr[rdi] + popfq mov qword ptr CXT_TO_DST[r8], rax mov qword ptr CXT_TO_SRC[r8], rdx diff --git a/gvm_types.h b/gvm_types.h index 9c54710..883b445 100755 --- a/gvm_types.h +++ b/gvm_types.h @@ -803,6 +803,7 @@ extern int CPU_HAS_X86_FEATURE_RDTSCP; extern int CPU_HAS_X86_FEATURE_LBRV; extern int CPU_HAS_X86_FEATURE_NRIPS; extern int CPU_HAS_X86_FEATURE_SMEP; +extern int CPU_HAS_X86_FEATURE_SMAP; extern int CPU_HAS_X86_FEATURE_MPX; extern int CPU_HAS_X86_FEATURE_XSAVES; extern int CPU_HAS_X86_FEATURE_CONSTANT_TSC; diff --git a/ntkrutils.c b/ntkrutils.c index 2509940..0d0bac3 100644 --- a/ntkrutils.c +++ b/ntkrutils.c @@ -35,6 +35,7 @@ int CPU_HAS_X86_FEATURE_RDTSCP; int CPU_HAS_X86_FEATURE_LBRV; int CPU_HAS_X86_FEATURE_NRIPS; int CPU_HAS_X86_FEATURE_SMEP; +int CPU_HAS_X86_FEATURE_SMAP; int CPU_HAS_X86_FEATURE_MPX; int CPU_HAS_X86_FEATURE_XSAVES; int CPU_HAS_X86_FEATURE_CONSTANT_TSC; @@ -400,11 +401,12 @@ static void cpu_features_init(void) check_cpu_has(X86_FEATURE_RDTSCP, 0x80000001, CPUID_EDX, 27); check_cpu_has_ex(X86_FEATURE_HLE, 7, 0, CPUID_EBX, 4); + check_cpu_has_ex(X86_FEATURE_SMEP, 7, 0, CPUID_EBX, 7); check_cpu_has_ex(X86_FEATURE_RTM, 7, 0, CPUID_EBX, 11); check_cpu_has_ex(X86_FEATURE_MPX, 7, 0, CPUID_EBX, 14); + check_cpu_has_ex(X86_FEATURE_SMAP, 7, 0, CPUID_EBX, 20); check_cpu_has_ex(X86_FEATURE_PKU, 7, 0, CPUID_ECX, 3); - check_cpu_has_ex(X86_FEATURE_SMEP, 7, 0, CPUID_ECX, 7); check_cpu_has(X86_FEATURE_NPT, 0x8000000a, CPUID_EDX, 0); check_cpu_has(X86_FEATURE_LBRV, 0x8000000a, CPUID_EDX, 1); diff --git a/ntkrutils.h b/ntkrutils.h index bea0a30..731c1aa 100644 --- a/ntkrutils.h +++ b/ntkrutils.h @@ -18,6 +18,7 @@ #include #include #include +#include // APC definitions (undocumented) typedef enum _KAPC_ENVIRONMENT @@ -949,6 +950,7 @@ static __inline size_t __copy_user(void *dst, const void *src, size_t size, { PMDL lock_mdl; HANDLE handle; + int clac = 0; lock_mdl = IoAllocateMdl(from? src : dst, size, FALSE, FALSE, NULL); if (!lock_mdl) @@ -957,7 +959,27 @@ static __inline size_t __copy_user(void *dst, const void *src, size_t size, handle = MmSecureVirtualMemory(from? src : dst, size, PAGE_READWRITE); if (!handle) return size; + /* + * If Windows turns on SMAP, we need set AC flag before accessing + * user addr. However, since we do not know Windows's logic for AC + * flag, we only turned it on the CPU this piece of code is running + * and make sure we are not interrupted in the middle (in case Windows + * has the chance to change the AC flag). + */ + if (boot_cpu_has(X86_FEATURE_SMAP)) { + local_irq_disable(); + if (__readcr4() & X86_CR4_SMAP && + !(__readeflags() & X86_EFLAGS_AC)) { + clac = 1; + _stac(); + } else + local_irq_enable(); + } memcpy(dst, src, size); + if (clac) { + _clac(); + local_irq_enable(); + } MmUnsecureVirtualMemory(handle); MmUnlockPages(lock_mdl); IoFreeMdl(lock_mdl);