[Bug 49221] New: Denuvo Anti-Cheat 'denuvo-anti-cheat.sys' needs instruction emulation for querying VMX capabilities via MSR 0x480..0x490

WineHQ Bugzilla wine-bugs at winehq.org
Fri May 22 07:36:07 CDT 2020


https://bugs.winehq.org/show_bug.cgi?id=49221

            Bug ID: 49221
           Summary: Denuvo Anti-Cheat 'denuvo-anti-cheat.sys' needs
                    instruction emulation for querying VMX capabilities
                    via MSR 0x480..0x490
           Product: Wine
           Version: 5.8
          Hardware: x86-64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: ntoskrnl
          Assignee: wine-bugs at winehq.org
          Reporter: focht at gmx.net
      Distribution: ---

Hello folks,

continuation of bug 49219 (split out from bug 49194).

--- snip ---
$ WINEDEBUG=+seh,+relay,+int,+ntoskrnl,+ntdll wine net start "Denuvo
Anti-Cheat" >>log.txt 2>&1
...
00d0:Call driver init 0000000000C81184
(obj=000000000078EE10,str=L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Denuvo
Anti-Cheat") 
...
00d0:Call ntoskrnl.exe.KeQueryActiveProcessorCountEx(0000ffff) ret=00c83d3a
00d0:fixme:ntoskrnl:KeQueryActiveProcessorCountEx GroupNumber 65535 semi-stub.
00d0:Call KERNEL32.GetSystemInfo(00b5f2f0) ret=00232926
00d0:Call ntdll.NtQuerySystemInformation(00000000,00b5f200,00000040,00000000)
ret=7b02c721
00d0:trace:ntdll:NtQuerySystemInformation
(0x00000000,0xb5f200,0x00000040,(nil))
00d0:Ret  ntdll.NtQuerySystemInformation() retval=00000000 ret=7b02c721
00d0:Call ntdll.NtQuerySystemInformation(00000001,00b5f1f0,0000000c,00000000)
ret=7b02c751
00d0:trace:ntdll:NtQuerySystemInformation
(0x00000001,0xb5f1f0,0x0000000c,(nil))
00d0:Ret  ntdll.NtQuerySystemInformation() retval=00000000 ret=7b02c751
00d0:Ret  KERNEL32.GetSystemInfo() retval=00000006 ret=00232926
00d0:Ret  ntoskrnl.exe.KeQueryActiveProcessorCountEx() retval=00000008
ret=00c83d3a
00d0:Call ntoskrnl.exe.KeSetSystemAffinityThreadEx(ffffffffffffffff)
ret=00c83d56
00d0:fixme:ntoskrnl:KeSetSystemAffinityThreadEx (0xffffffff) semi-stub
00d0:Call
ntdll.NtQueryInformationThread(fffffffffffffffe,0000001e,00b5f300,00000010,00000000)
ret=00232aa8
00d0:Ret  ntdll.NtQueryInformationThread() retval=00000000 ret=00232aa8
00d0:Call
ntdll.NtSetInformationThread(fffffffffffffffe,0000001e,00b5f310,00000010)
ret=00232b00
00d0:Ret  ntdll.NtSetInformationThread() retval=c000000d ret=00232b00
00d0:fixme:ntoskrnl:KeSetSystemAffinityThreadEx Set affinity, status
0xc000000d.
00d0:fixme:ntoskrnl:KeSetSystemAffinityThreadEx old.Group 0, old.Mask 0xff.
00d0:Ret  ntoskrnl.exe.KeSetSystemAffinityThreadEx() retval=000000ff
ret=00c83d56
00d0:Call ntoskrnl.exe.KeSetSystemAffinityThreadEx(00000001) ret=00c83d86
00d0:fixme:ntoskrnl:KeSetSystemAffinityThreadEx (0x1) semi-stub
00d0:Call
ntdll.NtQueryInformationThread(fffffffffffffffe,0000001e,00b5f300,00000010,00000000)
ret=00232aa8
00d0:Ret  ntdll.NtQueryInformationThread() retval=00000000 ret=00232aa8
00d0:Call
ntdll.NtSetInformationThread(fffffffffffffffe,0000001e,00b5f310,00000010)
ret=00232b00
00d0:Ret  ntdll.NtSetInformationThread() retval=00000000 ret=00232b00
00d0:fixme:ntoskrnl:KeSetSystemAffinityThreadEx old.Group 0, old.Mask 0xff.
00d0:Ret  ntoskrnl.exe.KeSetSystemAffinityThreadEx() retval=000000ff
ret=00c83d86
00d0:trace:seh:raise_exception code=c0000096 flags=0 addr=0xc88ac3 ip=c88ac3
tid=00d0
00d0:trace:seh:raise_exception  rax=0000000000000000 rbx=0000000000000000
rcx=00000000008e0370 rdx=000000009c000400
00d0:trace:seh:raise_exception  rsi=00000000008e1f70 rdi=00000000008e0370
rbp=0000000000b5f370 rsp=0000000000b5f2f8
00d0:trace:seh:raise_exception   r8=000000000027efb1  r9=00000000008e0370
r10=0000000000000000 r11=0000000000000000
00d0:trace:seh:raise_exception  r12=0000000000000000 r13=00007fffffea4000
r14=0000000000000000 r15=0000000080000008
00d0:trace:seh:call_vectored_handlers calling handler at 0x22cfa0 code=c0000096
flags=0
00d0:trace:int:emulate_instruction mov cr4,rax at c88ac3
00d0:trace:int:vectored_handler next instruction rip=c88ac6
00d0:trace:int:vectored_handler   rax=0000000000000000 rbx=0000000000000000
rcx=00000000008e0370 rdx=000000009c000400
00d0:trace:int:vectored_handler   rsi=00000000008e1f70 rdi=00000000008e0370
rbp=0000000000b5f370 rsp=0000000000b5f2f8
00d0:trace:int:vectored_handler    r8=000000000027efb1  r9=00000000008e0370
r10=0000000000000000 r11=0000000000000000
00d0:trace:int:vectored_handler   r12=0000000000000000 r13=00000000ffea4000
r14=0000000000000000 r15=0000000080000008
00d0:trace:seh:call_vectored_handlers handler at 0x22cfa0 returned ffffffff
00d0:trace:seh:raise_exception code=c0000005 flags=0 addr=0xc88ad4 ip=c88ad4
tid=00d0
00d0:trace:seh:raise_exception  info[0]=0000000000000000
00d0:trace:seh:raise_exception  info[1]=ffffffffffffffff
00d0:trace:seh:raise_exception  rax=0000000000000000 rbx=0000000000000000
rcx=0000000000000480 rdx=000000009c000400
00d0:trace:seh:raise_exception  rsi=00000000008e1f70 rdi=00000000008e0370
rbp=0000000000b5f370 rsp=0000000000b5f2f8
00d0:trace:seh:raise_exception   r8=000000000027efb1  r9=00000000008e0370
r10=0000000000000000 r11=0000000000000000
00d0:trace:seh:raise_exception  r12=0000000000000000 r13=00007fffffea4000
r14=0000000000000000 r15=0000000080000008
00d0:trace:seh:call_vectored_handlers calling handler at 0x22cfa0 code=c0000005
flags=0
00d0:trace:int:emulate_instruction rdmsr CR 0x00000480
00d0:trace:seh:call_vectored_handlers handler at 0x22cfa0 returned 0
00d0:warn:seh:virtual_unwind exception data not found in
L"denuvo-anti-cheat.sys" 
--- snip ---

Relevant disassembly snippet of driver:

--- snip ---
0000000140008AC0 | 4C:8BC9                | mov r9,rcx                      |
0000000140008AC3 | 0F20E0                 | mov rax,cr4                     |
0000000140008AC6 | 48:C1E8 0D             | shr rax,D                       |
0000000140008ACA | 24 01                  | and al,1                        |
0000000140008ACC | 8841 51                | mov byte ptr ds:[rcx+51],al     |
--- snip ---

CR4 -> bit 13 set -> VMXE

--- snip ---
0000000140008ACF | B9 80040000            | mov ecx,480                     |
0000000140008AD4 | 0F32                   | rdmsr                           |
0000000140008AD6 | 48:C1E2 20             | shl rdx,20                      |
0000000140008ADA | B9 81040000            | mov ecx,481                     |
0000000140008ADF | 48:0BC2                | or rax,rdx                      |
0000000140008AE2 | 49:8941 58             | mov qword ptr ds:[r9+58],rax    |
0000000140008AE6 | 0F32                   | rdmsr                           |
0000000140008AE8 | 48:C1E2 20             | shl rdx,20                      |
0000000140008AEC | B9 82040000            | mov ecx,482                     |
0000000140008AF1 | 48:0BC2                | or rax,rdx                      |
0000000140008AF4 | 49:8941 60             | mov qword ptr ds:[r9+60],rax    |
0000000140008AF8 | 0F32                   | rdmsr                           |
0000000140008AFA | 48:C1E2 20             | shl rdx,20                      |
0000000140008AFE | B9 83040000            | mov ecx,483                     |
0000000140008B03 | 48:0BC2                | or rax,rdx                      |
0000000140008B06 | 4C:8BC0                | mov r8,rax                      |
0000000140008B09 | 49:8941 68             | mov qword ptr ds:[r9+68],rax    |
0000000140008B0D | 0F32                   | rdmsr                           |
0000000140008B0F | 48:C1E2 20             | shl rdx,20                      |
0000000140008B13 | B9 84040000            | mov ecx,484                     |
0000000140008B18 | 48:0BC2                | or rax,rdx                      |
0000000140008B1B | 49:8941 70             | mov qword ptr ds:[r9+70],rax    |
0000000140008B1F | 0F32                   | rdmsr                           |
0000000140008B21 | 48:C1E2 20             | shl rdx,20                      |
0000000140008B25 | B9 85040000            | mov ecx,485                     |
0000000140008B2A | 48:0BC2                | or rax,rdx                      |
0000000140008B2D | 49:8941 78             | mov qword ptr ds:[r9+78],rax    |
0000000140008B31 | 0F32                   | rdmsr                           |
0000000140008B33 | 48:C1E2 20             | shl rdx,20                      |
0000000140008B37 | B9 86040000            | mov ecx,486                     |
0000000140008B3C | 48:0BC2                | or rax,rdx                      |
0000000140008B3F | 49:8981 80000000       | mov qword ptr ds:[r9+80],rax    |
0000000140008B46 | 0F32                   | rdmsr                           |
0000000140008B48 | 48:C1E2 20             | shl rdx,20                      |
0000000140008B4C | B9 87040000            | mov ecx,487                     |
0000000140008B51 | 48:0BC2                | or rax,rdx                      |
0000000140008B54 | 49:8981 88000000       | mov qword ptr ds:[r9+88],rax    |
0000000140008B5B | 0F32                   | rdmsr                           |
0000000140008B5D | 48:C1E2 20             | shl rdx,20                      |
0000000140008B61 | B9 88040000            | mov ecx,488                     |
0000000140008B66 | 48:0BC2                | or rax,rdx                      |
0000000140008B69 | 49:8981 90000000       | mov qword ptr ds:[r9+90],rax    |
0000000140008B70 | 0F32                   | rdmsr                           |
0000000140008B72 | 48:C1E2 20             | shl rdx,20                      |
0000000140008B76 | B9 89040000            | mov ecx,489                     |
0000000140008B7B | 48:0BC2                | or rax,rdx                      |
0000000140008B7E | 49:8981 98000000       | mov qword ptr ds:[r9+98],rax    |
0000000140008B85 | 0F32                   | rdmsr                           |
0000000140008B87 | 48:C1E2 20             | shl rdx,20                      |
0000000140008B8B | B9 8A040000            | mov ecx,48A                     |
0000000140008B90 | 48:0BC2                | or rax,rdx                      |
0000000140008B93 | 49:8981 A0000000       | mov qword ptr ds:[r9+A0],rax    |
0000000140008B9A | 0F32                   | rdmsr                           |
0000000140008B9C | 48:C1E2 20             | shl rdx,20                      |
0000000140008BA0 | 45:33D2                | xor r10d,r10d                   |
0000000140008BA3 | 48:0BC2                | or rax,rdx                      |
0000000140008BA6 | 49:8981 A8000000       | mov qword ptr ds:[r9+A8],rax    |
0000000140008BAD | 4D:85C0                | test r8,r8                      |
0000000140008BB0 | 79 3B                  | jns denuvo-anti-cheat.140008BED |
0000000140008BB2 | B9 8B040000            | mov ecx,48B                     |
0000000140008BB7 | 0F32                   | rdmsr                           |
0000000140008BB9 | 48:C1E2 20             | shl rdx,20                      |
0000000140008BBD | 48:B9 0000000022000000 | mov rcx,2200000000              |
0000000140008BC7 | 48:0BC2                | or rax,rdx                      |
0000000140008BCA | 49:8981 B0000000       | mov qword ptr ds:[r9+B0],rax    |
0000000140008BD1 | 48:85C1                | test rcx,rax                    |
0000000140008BD4 | 74 1E                  | je denuvo-anti-cheat.140008BF4  |
0000000140008BD6 | B9 8C040000            | mov ecx,48C                     |
0000000140008BDB | 0F32                   | rdmsr                           |
0000000140008BDD | 48:C1E2 20             | shl rdx,20                      |
0000000140008BE1 | 48:0BC2                | or rax,rdx                      |
0000000140008BE4 | 49:8981 B8000000       | mov qword ptr ds:[r9+B8],rax    |
0000000140008BEB | EB 0E                  | jmp denuvo-anti-cheat.140008BFB |
0000000140008BED | 4D:8991 B0000000       | mov qword ptr ds:[r9+B0],r10    |
0000000140008BF4 | 4D:8991 B8000000       | mov qword ptr ds:[r9+B8],r10    |
0000000140008BFB | 48:B9 0000000000008000 | mov rcx,80000000000000          |
0000000140008C05 | 49:8549 58             | test qword ptr ds:[r9+58],rcx   |
0000000140008C09 | 74 5D                  | je denuvo-anti-cheat.140008C68  |
0000000140008C0B | B9 8D040000            | mov ecx,48D                     |
0000000140008C10 | 0F32                   | rdmsr                           |
0000000140008C12 | 48:C1E2 20             | shl rdx,20                      |
0000000140008C16 | B9 8E040000            | mov ecx,48E                     |
0000000140008C1B | 48:0BC2                | or rax,rdx                      |
0000000140008C1E | 49:8981 C0000000       | mov qword ptr ds:[r9+C0],rax    |
0000000140008C25 | 0F32                   | rdmsr                           |
0000000140008C27 | 48:C1E2 20             | shl rdx,20                      |
0000000140008C2B | B9 8F040000            | mov ecx,48F                     |
0000000140008C30 | 48:0BC2                | or rax,rdx                      |
0000000140008C33 | 49:8981 C8000000       | mov qword ptr ds:[r9+C8],rax    |
0000000140008C3A | 0F32                   | rdmsr                           |
0000000140008C3C | 48:C1E2 20             | shl rdx,20                      |
0000000140008C40 | B9 90040000            | mov ecx,490                     |
0000000140008C45 | 48:0BC2                | or rax,rdx                      |
0000000140008C48 | 49:8981 D0000000       | mov qword ptr ds:[r9+D0],rax    |
0000000140008C4F | 0F32                   | rdmsr                           |
0000000140008C51 | 48:C1E2 20             | shl rdx,20                      |
0000000140008C55 | 48:0BC2                | or rax,rdx                      |
0000000140008C58 | 49:8981 D8000000       | mov qword ptr ds:[r9+D8],rax    |
0000000140008C5F | 41:C741 54 11000000    | mov dword ptr ds:[r9+54],11     |
0000000140008C67 | C3                     | ret                             |
0000000140008C68 | 4D:8991 D8000000       | mov qword ptr ds:[r9+D8],r10    |
0000000140008C6F | 4D:8991 D0000000       | mov qword ptr ds:[r9+D0],r10    |
0000000140008C76 | 4D:8991 C8000000       | mov qword ptr ds:[r9+C8],r10    |
0000000140008C7D | 4D:8991 C0000000       | mov qword ptr ds:[r9+C0],r10    |
0000000140008C84 | 41:C741 54 11000000    | mov dword ptr ds:[r9+54],11     |
0000000140008C8C | C3                     | ret                             |
--- snip ---

The patch (hack) from https://bugs.winehq.org/show_bug.cgi?id=49194#c1 returns
zero rax and rdx for any MSR which isn't recognized in 'emulate_instruction()' 

Wine source:

https://source.winehq.org/git/wine.git/blob/b65ca133052ed9053e48c571155a764d4d711277:/dlls/ntoskrnl.exe/instr.c#l769

--- snip ---
 769         case 0x32: /* rdmsr */
 770         {
 771             ULONG reg = context->Rcx;
 772             TRACE("rdmsr CR 0x%08x\n", reg);
 773             switch (reg)
 774             {
 775             case MSR_LSTAR:
 776             {
 777                 ULONG_PTR syscall_address =
(ULONG_PTR)fake_syscall_function;
 778                 context->Rdx = (ULONG)(syscall_address >> 32);
 779                 context->Rax = (ULONG)syscall_address;
 780                 break;
 781             }
 782             default: return ExceptionContinueSearch;
 783             }
 784             context->Rip += prefixlen + 2;
 785             return ExceptionContinueExecution;
 786         }
--- snip ---

Since the VMX MSR range is well known there could be a default handler for
these regs, returning fake (0) values.

---

Tidbits:

Python app to dump VMX capabilities from userspace:

https://github.com/qemu/qemu/blob/master/scripts/kvm/vmxcap

--- snip ---
$ sudo ./vmxcap.py 

Basic VMX Information
  Hex: 0xda040000000012
  Revision                                 18
  VMCS size                                1024
  VMCS restricted to 32 bit addresses      no
  Dual-monitor support                     yes
  VMCS memory type                         6
  INS/OUTS instruction information         yes
  IA32_VMX_TRUE_*_CTLS support             yes
pin-based controls
  External interrupt exiting               yes
  NMI exiting                              yes
  Virtual NMIs                             yes
  Activate VMX-preemption timer            yes
  Process posted interrupts                no
primary processor-based controls
  Interrupt window exiting                 yes
  Use TSC offsetting                       yes
  HLT exiting                              yes
  INVLPG exiting                           yes
  MWAIT exiting                            yes
  RDPMC exiting                            yes
  RDTSC exiting                            yes
  CR3-load exiting                         default
  CR3-store exiting                        default
  CR8-load exiting                         yes
  CR8-store exiting                        yes
  Use TPR shadow                           yes
  NMI-window exiting                       yes
  MOV-DR exiting                           yes
  Unconditional I/O exiting                yes
  Use I/O bitmaps                          yes
  Monitor trap flag                        yes
  Use MSR bitmaps                          yes
  MONITOR exiting                          yes
  PAUSE exiting                            yes
  Activate secondary control               yes
secondary processor-based controls
  Virtualize APIC accesses                 yes
  Enable EPT                               yes
  Descriptor-table exiting                 yes
  Enable RDTSCP                            yes
  Virtualize x2APIC mode                   yes
  Enable VPID                              yes
  WBINVD exiting                           yes
  Unrestricted guest                       yes
  APIC register emulation                  no
  Virtual interrupt delivery               no
  PAUSE-loop exiting                       yes
  RDRAND exiting                           yes
  Enable INVPCID                           yes
  Enable VM functions                      yes
  VMCS shadowing                           no
  Enable ENCLS exiting                     no
  RDSEED exiting                           no
  Enable PML                               no
  EPT-violation #VE                        no
  Conceal non-root operation from PT       no
  Enable XSAVES/XRSTORS                    no
  Mode-based execute control (XS/XU)       no
  Sub-page write permissions               no
  GPA translation for PT                   no
  TSC scaling                              no
  User wait and pause                      no
  ENCLV exiting                            no
VM-Exit controls
  Save debug controls                      default
  Host address-space size                  yes
  Load IA32_PERF_GLOBAL_CTRL               yes
  Acknowledge interrupt on exit            yes
  Save IA32_PAT                            yes
  Load IA32_PAT                            yes
  Save IA32_EFER                           yes
  Load IA32_EFER                           yes
  Save VMX-preemption timer value          yes
  Clear IA32_BNDCFGS                       no
  Conceal VM exits from PT                 no
  Clear IA32_RTIT_CTL                      no
VM-Entry controls
  Load debug controls                      default
  IA-32e mode guest                        yes
  Entry to SMM                             yes
  Deactivate dual-monitor treatment        yes
  Load IA32_PERF_GLOBAL_CTRL               yes
  Load IA32_PAT                            yes
  Load IA32_EFER                           yes
  Load IA32_BNDCFGS                        no
  Conceal VM entries from PT               no
  Load IA32_RTIT_CTL                       no
Miscellaneous data
  Hex: 0x300481e5
  VMX-preemption timer scale (log2)        5
  Store EFER.LMA into IA-32e mode guest control yes
  HLT activity state                       yes
  Shutdown activity state                  yes
  Wait-for-SIPI activity state             yes
  PT in VMX operation                      no
  IA32_SMBASE support                      yes
  Number of CR3-target values              4
  MSR-load/store count recommendation      0
  IA32_SMM_MONITOR_CTL[2] can be set to 1  yes
  VMWRITE to VM-exit information fields    yes
  Inject event with insn length=0          no
  MSEG revision identifier                 0
VPID and EPT capabilities
  Hex: 0xf0106334141
  Execute-only EPT translations            yes
  Page-walk length 4                       yes
  Paging-structure memory type UC          yes
  Paging-structure memory type WB          yes
  2MB EPT pages                            yes
  1GB EPT pages                            yes
  INVEPT supported                         yes
  EPT accessed and dirty flags             yes
  Advanced VM-exit information for EPT violations no
  Single-context INVEPT                    yes
  All-context INVEPT                       yes
  INVVPID supported                        yes
  Individual-address INVVPID               yes
  Single-context INVVPID                   yes
  All-context INVVPID                      yes
  Single-context-retaining-globals INVVPID yes
VM Functions
  Hex: 0x1
  EPTP Switching                           yes
--- snip ---

Poor man's version (msr-tools):

--- snip ---
$ for i in `seq 0x480 0x490` ; do sudo rdmsr -x $i ; done

da040000000012
7f00000016
fff9fffe0401e172
7fffff00036dff
ffff000011ff
300481e5
80000021
ffffffff
2000
1727ff
2a
3cff00000000
f0106334141
7f00000016
fff9fffe04006172
7fffff00036dfb
ffff000011fb
--- snip ---

$ wine --version
wine-5.8-321-gf0a8061663

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list