[Bug 48997] New: Riot Vanguard (Riot Games) 'vgk.sys' crashes in driver entry (needs more reasonable CR0 register values in instruction emulation)

WineHQ Bugzilla wine-bugs at winehq.org
Wed Apr 22 16:05:22 CDT 2020


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

            Bug ID: 48997
           Summary: Riot Vanguard (Riot Games) 'vgk.sys' crashes in driver
                    entry (needs more reasonable CR0 register values in
                    instruction emulation)
           Product: Wine
           Version: 5.6
          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,

as it says.

--- snip ---
$ WINEDEBUG=+seh,+loaddll,+process,+ntoskrnl wine net start vgc >>log.txt 2>&1
...
001b:fixme:ntoskrnl:KeIpiGenericCall stub: 0000000000D61D74 0000000000000000
...
001b:trace:seh:raise_exception code=c0000096 flags=0 addr=0xf38ec7 ip=f38ec7
tid=001b
001b:trace:seh:raise_exception  rax=0000000000000078 rbx=fffffffffff49c55
rcx=0000000000000000 rdx=00000000000fda18
001b:trace:seh:raise_exception  rsi=0000000000e07fec rdi=00000000000000e8
rbp=000000000002c1d1 rsp=0000000000c3f4f0
001b:trace:seh:raise_exception   r8=00000000000f174d  r9=0000000000c3f710
r10=00000000000fda18 r11=0000000000f38ec7
001b:trace:seh:raise_exception  r12=00000000000fd8b0 r13=00007fffffea4000
r14=00000000000fda18 r15=0000000000000000
001b:trace:seh:call_vectored_handlers calling handler at 0x18000b9f0
code=c0000096 flags=0
001b:trace:seh:call_vectored_handlers handler at 0x18000b9f0 returned ffffffff
...
001b:trace:seh:raise_exception code=c000001d flags=0 addr=0x104bc20 ip=104bc20
tid=001b
001b:trace:seh:raise_exception  rax=0000000000b41d20 rbx=00000000000fda18
rcx=0000000000000000 rdx=000000000000004d
001b:trace:seh:raise_exception  rsi=0000000000c3f82c rdi=00000000000fda18
rbp=00000000000fc868 rsp=0000000000c3f740
001b:trace:seh:raise_exception   r8=0000000000000000  r9=0000000000000000
r10=0000000000000000 r11=0000000000000000
001b:trace:seh:raise_exception  r12=00000000000fd8b0 r13=00007fffffea4000
r14=00000000000fda18 r15=0000000000000000
001b:trace:seh:call_vectored_handlers calling handler at 0x18000b9f0
code=c000001d flags=0
001b:trace:seh:call_vectored_handlers handler at 0x18000b9f0 returned 0
001b:trace:seh:RtlVirtualUnwind type 1 rip 104bc20 rsp c3f740
001b:trace:seh:dump_unwind_info **** func 2ebbd7-2ebc54
...
--- snip ---

Yes, I know 'int' debug channel which shows the faulting/emulated instruction
decoding. I forgot to run it in first place before I fixed the problem ;-)

The unhandled invalid instruction exception following the CR0 emulation
exception is the result of misguided control flow due to Wine's strange default
value.

Relevant driver disassembly:

--- snip ---
...
0000000000F38EC7 | 0F20C2           | mov rdx,cr0                | read CR0
0000000000F38ECA | 81ED 8836F674    | sub ebp,74F63688           |
0000000000F38ED0 | 40:C0F5 36       | shl bpl,36                 |
0000000000F38ED4 | 0FB7E9           | movzx ebp,cx               |
0000000000F38ED7 | 49:81E9 08000000 | sub r9,8                   |
0000000000F38EDE | 40:0F92C5        | setb bpl                   |
0000000000F38EE2 | 66:0FBAF5 B7     | btr bp,B7                  |
0000000000F38EE7 | 66:8BEB          | mov bp,bx                  |
0000000000F38EEA | 49:8911          | mov qword ptr ds:[r9],rdx  | save val
0000000000F38EED | 6641:0BEA        | or bp,r10w                 |
0000000000F38EF1 | 48:81EE 04000000 | sub rsi,4                  |
0000000000F38EF8 | 48:F7DD          | neg rbp                    |
0000000000F38EFB | 8B2E             | mov ebp,dword ptr ds:[rsi] |
0000000000F38EFD | 40:F6C4 F2       | test spl,F2                |
0000000000F38F01 | 41:80FA AD       | cmp r10b,AD                |
0000000000F38F05 | F8               | clc                        |
0000000000F38F06 | 41:33E8          | xor ebp,r8d                |
0000000000F38F09 | F9               | stc                        |
0000000000F38F0A | D1CD             | ror ebp,1                  |
0000000000F38F0C | F9               | stc                        |
0000000000F38F0D | 0FCD             | bswap ebp                  |
0000000000F38F0F | 6641:3BF3        | cmp si,r11w                |
0000000000F38F13 | 81C5 66295D17    | add ebp,175D2966           |
0000000000F38F19 | F9               | stc                        |
0000000000F38F1A | F8               | clc                        |
0000000000F38F1B | F7D5             | not ebp                    |
0000000000F38F1D | E9 D51F0400      | jmp vgk.F7AEF7             |
...
--- snip ---

I found this interesting document which shows the system/special register
values of many Window versions, Linux and even Wine:

https://github.com/corkami/docs/blob/master/InitialValues.md

--- snip ---
Wine

tested under Debian

Detect Wine:

    GS (3B/6B)
    FS (33/63)
    CR0 (80050033)
    ...
--- snip ---

The document was added to Github repo in April 2017. The Wine version at this
point was likely Wine 2.6-ish.

I couldn't find a place in Wine sources where this value 0x80050033 is set.
Git history shows it was always 0x10 (x86 instruction emulation).

My guess would be whoever tested under Wine probably used the unprivileged
'smsw' instruction which doesn't cause a trap in usermode (not emulated in
Wine). I wrote small test app which is basically 'asm("smsw %0" : "=r"(cr0));'
and indeed 0x80050033 value is returned for CR0 in x86_64 Linux.

https://source.winehq.org/git/wine.git/blob/709935314458bd0ce27aab3986ae98cc556cb663:/dlls/ntoskrnl.exe/instr.c#l327

The x86_64 instruction emulation for CRx, DRx was added here:

https://source.winehq.org/git/wine.git/commitdiff/ce09790d29630a6a4c0cd49459afc2097700ad10
("ntoskrnl: Add emulation of CRn and DRn registers on x86-64.")

Tracked by bug 44530 ("64-bit Sentinel HASP hardlock.sys kernel driver tries to
access to DR7 (not handled in ntoskrnl emulate_instruction)").

---

Anyway, I think Wine using CR0 default value 0x80050031 or 0x80050033 should be
fine.

0x80050031 = '1000'0000'0000'0101'0000'0000'0011'0001

From: https://en.wikipedia.org/wiki/Control_register

Only showing the set bits meaning here:

| Bit | Name | Full Name               |
----------------------------------------
|   0 |  PE  | Protected Mode Enable   |
|   4 |  ET  | Extension type          |
|   5 |  NE  | Numeric error           |
|  16 |  WP  | Write protect           |
|  18 |  AM  | Alignment mask          |
|  31 |  PG  | Paging                  |
----------------------------------------

Wine source:

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

--- snip ---
...
 691     /* Now look at the actual instruction */
 692 
 693     switch(*instr)
 694     {
 695     case 0x0f: /* extended instruction */
 696         switch(instr[1])
 697         {
 698         case 0x20: /* mov crX, Rd */
 699         {
 700             int reg = REGMODRM_REG( instr[2], rex );
 701             int rm = REGMODRM_RM( instr[2], rex );
 702             DWORD64 *data = get_int_reg( context, rm );
 703             TRACE( "mov cr%u,%s at %lx\n", reg, reg_names[rm],
context->Rip );
 704             switch (reg)
 705             {
 706             case 0: *data = 0x10; break; /* FIXME: set more bits ? */
 707             case 2: *data = 0; break;
 708             case 3: *data = 0; break;
 709             case 4: *data = 0; break;
 710             case 8: *data = 0; break;
 711             default: return ExceptionContinueSearch;
 712             }
 713             context->Rip += prefixlen + 3;
 714             return ExceptionContinueExecution;
 715         }
...
--- snip ---

$ sha1sum setup.exe 
08deca4c0b46a3481e706926c0217d1c944d22a3  setup.exe

$ du -sh setup.exe 
15M    setup.exe

$ wine --version
wine-5.6-258-gf31a29b8d1

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