xgetbv is compiled via the intrinsic _xgetbv defined in immintrin.h
as far as i know only one register is defined XCR0 == 0
but this intrinsic also takes 1 as its parameter
and returns result in EAX:EDX (this can probably be used as an anti debugging feature )
because the results are different inside and outside of debugger (3 no debugger ,7 with debugger afaik)
Code: Select all
:\>f:\git\usr\bin\grep -ir xcr --include=*.h *
immintrin.h:#define _XCR_XFEATURE_ENABLED_MASK 0
:\>f:\git\usr\bin\grep -n -A 6 -B 6 -ir xcr --include=*.h *
immintrin.h-1082-
immintrin.h-1083-/* Start of new intrinsics for Dev10 SP1
immintrin.h-1084- *
immintrin.h-1085- * The list of extended control registers.
immintrin.h-1086- * Currently, the list includes only one register.
immintrin.h-1087- */
immintrin.h:1088:#define _XCR_XFEATURE_ENABLED_MASK 0
immintrin.h-1089-
immintrin.h-1090-/* Returns the content of the specified extended control register */
immintrin.h-1091-extern unsigned __int64 __cdecl _xgetbv(unsigned int ext_ctrl_reg);
immintrin.h-1092-
immintrin.h-1093-/* Writes the value to the specified extended control register */
immintrin.h-1094-extern void __cdecl _xsetbv(unsigned int ext_ctrl_reg, unsigned __int64 val);
you can use windbg in kmode to look at xcr0
Code: Select all
0: kd> dx @$curprocess.Threads.First().Registers.Kernel
@$curprocess.Threads.First().Registers.Kernel
cr0 : 0x80050033
cr2 : 0xffffe70634a784c0
cr3 : 0x45f81002
cr4 : 0x170678
cr8 : 0x0
gdtr : 0xfffff802531f0fb0
gdtl : 0x57
idtr : 0xfffff802531ee000
idtl : 0xfff
tr : 0x40
ldtr : 0x0
kmxcsr : 0x1f80
kdr0 : 0x0
kdr1 : 0x0
kdr2 : 0x0
kdr3 : 0x0
kdr6 : 0xffff0ff0
kdr7 : 0x400
xcr0 : 0x1f <<<<<<
nothing special needed like registry or whatever it will compile and run correctly without any cpuid if you have a computer that can use that instruction as below
Code: Select all
#include <stdio.h>
#include <windows.h>
#include <intrin.h>
#include <excpt.h>
unsigned long long foo = 0;
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
if (code == EXCEPTION_ACCESS_VIOLATION)
{
printf("Access Violation ");
foo = 0;
return EXCEPTION_EXECUTE_HANDLER;
}
else
{
puts("didn't catch AV, unexpected.");
return EXCEPTION_CONTINUE_SEARCH;
};
}
void main(void)
{
printf("lets print some xcrs\n");
for (int i=0;i<0x10;i++){
__try {
foo = _xgetbv(i);
printf( " %x = %I64X\n" , i,foo);
}__except(filter(GetExceptionCode(), GetExceptionInformation()))
{
printf( "%x = %I64X\n" , i,foo);
}
}
}
will return
Code: Select all
:\>sixcr.exe
lets print some xcrs
0 = 1F
1 = 3
Access Violation 2 = 0
Access Violation 3 = 0
Access Violation 4 = 0
Access Violation 5 = 0
Access Violation 6 = 0
Access Violation 7 = 0
Access Violation 8 = 0
Access Violation 9 = 0
Access Violation a = 0
Access Violation b = 0
Access Violation c = 0
Access Violation d = 0
Access Violation e = 0
Access Violation f = 0
disassembly of main
Code: Select all
0:000> uf .
sixcr!main:
00007ff7`45881050 4883ec38 sub rsp,38h
00007ff7`45881054 488d0d1dd30400 lea rcx,[sixcr!__xt_z+0x40 (00007ff7`458ce378)]
00007ff7`4588105b e8d0000000 call sixcr!printf (00007ff7`45881130)
00007ff7`45881060 c744242000000000 mov dword ptr [rsp+20h],0
00007ff7`45881068 eb0a jmp sixcr!main+0x24 (00007ff7`45881074) Branch
sixcr!main+0x1a:
00007ff7`4588106a 8b442420 mov eax,dword ptr [rsp+20h]
00007ff7`4588106e ffc0 inc eax
00007ff7`45881070 89442420 mov dword ptr [rsp+20h],eax
sixcr!main+0x24:
00007ff7`45881074 837c242010 cmp dword ptr [rsp+20h],10h
00007ff7`45881079 7d4b jge sixcr!main+0x76 (00007ff7`458810c6) Branch
sixcr!main+0x2b:
00007ff7`4588107b 8b4c2420 mov ecx,dword ptr [rsp+20h]
00007ff7`4588107f 0f01d0 xgetbv
00007ff7`45881082 48c1e220 shl rdx,20h
00007ff7`45881086 480bd0 or rdx,rax
00007ff7`45881089 488bc2 mov rax,rdx
00007ff7`4588108c 4889053deb0500 mov qword ptr [sixcr!foo (00007ff7`458dfbd0)],rax
00007ff7`45881093 4c8b0536eb0500 mov r8,qword ptr [sixcr!foo (00007ff7`458dfbd0)]
00007ff7`4588109a 8b542420 mov edx,dword ptr [rsp+20h]
00007ff7`4588109e 488d0debd20400 lea rcx,[sixcr!__xt_z+0x58 (00007ff7`458ce390)]
00007ff7`458810a5 e886000000 call sixcr!printf (00007ff7`45881130)
00007ff7`458810aa eb18 jmp sixcr!main+0x74 (00007ff7`458810c4) Branch
sixcr!main+0x74:
00007ff7`458810c4 eba4 jmp sixcr!main+0x1a (00007ff7`4588106a) Branch
sixcr!main+0x76:
00007ff7`458810c6 33c0 xor eax,eax
00007ff7`458810c8 4883c438 add rsp,38h
00007ff7`458810cc c3 ret
different results for ecx =1 inside and outside of debugger
Code: Select all
:\>sixcr.exe
lets print some xcrs
0 = 1F
1 = 3 <<<<<<<<<<<<< outside debugger
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
:\>cdb -c "g;q" sixcr.exe
Microsoft (R) Windows Debugger Version 10.0.17763.132 AMD64
0:000> cdb: Reading initial command 'g;q'
lets print some xcrs
0 = 1F
1 = 7 <<<<<<<<<<<< inside debugger
(2d5c.2b9c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
quit: