[Bug 43567] Vietcong - game crashes during radiocalls ('kernel32.GetTickCount' clobbers ECX)

WineHQ Bugzilla wine-bugs at winehq.org
Wed Dec 2 08:51:10 CST 2020


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

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Vietcong - game crashes     |Vietcong - game crashes
                   |during radiocalls           |during radiocalls
                   |                            |('kernel32.GetTickCount'
                   |                            |clobbers ECX)
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |FIXED
           Keywords|                            |download, obfuscation
      Fixed by SHA1|                            |cd215bb49bc240cdce5415c8026
                   |                            |4f8daa557636a
                 CC|                            |focht at gmx.net

--- Comment #9 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

this has been fixed some time ago.

I made some effort to document 'kernel32.GetTickCount' API entry point
"history" for the sake of those interested (foremost myself).

First the commit that influenced the code generation (via build system/compiler
settings, code changes, ...), followed by disassembly to show where/when ECX
gets clobbered. NOTE: '(func-1)' is used to work around symbol processing
problem for hotpatch entries.

Starting with Wine l33t release (old enough)

--- snip ---
$ gdb mainline-install-1.3.37-x86_64/lib/wine/kernel32.dll.so -batch -ex
'disassemble GetTickCount'
Dump of assembler code for function GetTickCount:
   0x0003f870 <+0>:    push   %ebp
   0x0003f871 <+1>:    mov    %esp,%ebp
   0x0003f873 <+3>:    push   %ebx
   0x0003f874 <+4>:    call   0x1f760 <__x86.get_pc_thunk.bx>
   0x0003f879 <+9>:    add    $0x5b787,%ebx
   0x0003f87f <+15>:    sub    $0x4,%esp
   0x0003f882 <+18>:    call   0x3f820 <GetTickCount64>
   0x0003f887 <+23>:    mov    -0x4(%ebp),%ebx
   0x0003f88a <+26>:    leave  
   0x0003f88b <+27>:    ret    

--- snip ---

https://source.winehq.org/git/wine.git/commitdiff/1005f3a6fa9d1aeb3e0e912815d12f7b1ed94b0c
("kernel32: Make GetTickCount and GetTickCount64 hotpatchable.")

--- snip ---
gdb mainline-install-1.7.33-x86_64/lib/wine/kernel32.dll.so -batch -ex
'disassemble GetTickCount-1'

Dump of assembler code for function GetTickCount:
   0x7b843820 <+0>:    mov    %edi,%edi
   0x7b843822 <+2>:    push   %ebp
   0x7b843823 <+3>:    mov    %esp,%ebp
   0x7b843825 <+0>:    push   %ebx
   0x7b843826 <+1>:    call   0x7b820770 <__x86.get_pc_thunk.bx>
   0x7b84382b <+6>:    add    $0x707d5,%ebx
   0x7b843831 <+12>:    and    $0xfffffff0,%esp
   0x7b843834 <+15>:    call   0x7b8437b0 <GetTickCount64>
   0x7b843839 <+20>:    mov    -0x4(%ebp),%ebx
   0x7b84383c <+23>:    leave
   0x7b84383d <+24>:    ret

$ gdb mainline-install-1.7.33-x86_64/lib/wine/kernel32.dll.so -batch -ex
'disassemble GetTickCount64-1'

Dump of assembler code for function GetTickCount64:
   0x7b8437b0 <+0>:    mov    %edi,%edi
   0x7b8437b2 <+2>:    push   %ebp
   0x7b8437b3 <+3>:    mov    %esp,%ebp
   0x7b8437b5 <+0>:    pop    %ebp
   0x7b8437b6 <+1>:    lea    0x4(%esp),%ecx
   0x7b8437ba <+5>:    and    $0xfffffff0,%esp
   0x7b8437bd <+8>:    pushl  -0x4(%ecx)
   0x7b8437c0 <+11>:    push   %ebp
   0x7b8437c1 <+12>:    mov    %esp,%ebp
   0x7b8437c3 <+14>:    push   %ebx
   0x7b8437c4 <+15>:    call   0x7b820770 <__x86.get_pc_thunk.bx>
   0x7b8437c9 <+20>:    add    $0x70837,%ebx
   0x7b8437cf <+26>:    push   %ecx
   0x7b8437d0 <+27>:    lea    -0x10(%ebp),%eax
   0x7b8437d3 <+30>:    sub    $0x18,%esp
   0x7b8437d6 <+33>:    push   %eax
   0x7b8437d7 <+34>:    lea    -0x18(%ebp),%eax
   0x7b8437da <+37>:    push   %eax
   0x7b8437db <+38>:    call   0x7b827854 <NtQueryPerformanceCounter>
   0x7b8437e0 <+43>:    imul   $0x3e8,-0x14(%ebp),%ecx
   0x7b8437e7 <+50>:    mov    $0x3e8,%eax
   0x7b8437ec <+55>:    mull   -0x18(%ebp)
   0x7b8437ef <+58>:    sub    $0x8,%esp
   0x7b8437f2 <+61>:    pushl  -0xc(%ebp)
   0x7b8437f5 <+64>:    pushl  -0x10(%ebp)
   0x7b8437f8 <+67>:    add    %ecx,%edx
   0x7b8437fa <+69>:    push   %edx
   0x7b8437fb <+70>:    push   %eax
   0x7b8437fc <+71>:    call   0x7b87c180 <__divdi3>
   0x7b843801 <+76>:    add    $0x18,%esp
   0x7b843804 <+79>:    lea    -0x8(%ebp),%esp
   0x7b843807 <+82>:    pop    %ecx
   0x7b843808 <+83>:    pop    %ebx
   0x7b843809 <+84>:    pop    %ebp
   0x7b84380a <+85>:    lea    -0x4(%ecx),%esp
   0x7b84380d <+88>:    ret
--- snip ---

https://source.winehq.org/git/wine.git/commitdiff/8f732c66ab37b54c30d63c74f7822ba1d4f04996
("makefiles: Build with -fno-PIC on i386.")

--- snip ---
$ gdb mainline-install-4.8-x86_64/lib/wine/kernel32.dll.so -batch -ex
'disassemble GetTickCount-1'

Dump of assembler code for function GetTickCount:
   0x7b45cff0 <+0>:    mov    %edi,%edi
   0x7b45cff2 <+2>:    push   %ebp
   0x7b45cff3 <+3>:    mov    %esp,%ebp
   0x7b45cff5 <+0>:    pop    %ebp
   0x7b45cff6 <+1>:    lea    0x4(%esp),%ecx
   0x7b45cffa <+5>:    and    $0xfffffff0,%esp
   0x7b45cffd <+8>:    pushl  -0x4(%ecx)
   0x7b45d000 <+11>:    push   %ebp
   0x7b45d001 <+12>:    mov    %esp,%ebp
   0x7b45d003 <+14>:    push   %ecx
   0x7b45d004 <+15>:    lea    -0x10(%ebp),%eax
   0x7b45d007 <+18>:    sub    $0x1c,%esp
   0x7b45d00a <+21>:    push   %eax
   0x7b45d00b <+22>:    lea    -0x18(%ebp),%eax
   0x7b45d00e <+25>:    push   %eax
   0x7b45d00f <+26>:    call   0x7b43c298 <NtQueryPerformanceCounter>
   0x7b45d014 <+31>:    imul   $0x3e8,-0x14(%ebp),%ecx
   0x7b45d01b <+38>:    mov    $0x3e8,%eax
   0x7b45d020 <+43>:    mull   -0x18(%ebp)
   0x7b45d023 <+46>:    sub    $0x8,%esp
   0x7b45d026 <+49>:    pushl  -0xc(%ebp)
   0x7b45d029 <+52>:    pushl  -0x10(%ebp)
   0x7b45d02c <+55>:    add    %ecx,%edx
   0x7b45d02e <+57>:    push   %edx
   0x7b45d02f <+58>:    push   %eax
   0x7b45d030 <+59>:    call   0x7b4a85c0 <__divdi3>
   0x7b45d035 <+64>:    mov    -0x4(%ebp),%ecx
   0x7b45d038 <+67>:    add    $0x18,%esp
   0x7b45d03b <+70>:    leave
   0x7b45d03c <+71>:    lea    -0x4(%ecx),%esp
   0x7b45d03f <+74>:    ret
--- snip ---

https://source.winehq.org/git/wine.git/commitdiff/3e927c4aec9dbeef930b83f62ee0651b8c147247
("ntdll: Extend NtGetTickCount() to return 64-bits. Forward kernel32 functions
to it.")

--- snip ---
$ gdb mainline-install-4.9-x86_64/lib/wine/kernel32.dll.so -batch -ex
'disassemble GetTickCount-1'

No symbol "GetTickCount" in current context.
--- snip ---

https://source.winehq.org/git/wine.git/commitdiff/13e11d3fcbcf8790e031c4bc52f5f550b1377b3b
("kernel32: Move the implementation of GetTickCount() to kernel32.")

--- snip ---
$ gdb mainline-install-4.10-x86_64/lib/wine/kernel32.dll.so -batch -ex
'disassemble GetTickCount-1'

Dump of assembler code for function GetTickCount:
   0x7b49a3c0 <+0>:    mov    %edi,%edi
   0x7b49a3c2 <+2>:    push   %ebp
   0x7b49a3c3 <+3>:    mov    %esp,%ebp
   0x7b49a3c5 <+0>:    pop    %ebp
   0x7b49a3c6 <+1>:    lea    0x4(%esp),%ecx
   0x7b49a3ca <+5>:    and    $0xfffffff0,%esp
   0x7b49a3cd <+8>:    pushl  -0x4(%ecx)
   0x7b49a3d0 <+11>:    push   %ebp
   0x7b49a3d1 <+12>:    mov    %esp,%ebp
   0x7b49a3d3 <+14>:    push   %esi
   0x7b49a3d4 <+15>:    push   %ebx
   0x7b49a3d5 <+16>:    lea    -0x20(%ebp),%ebx
   0x7b49a3d8 <+19>:    push   %ecx
   0x7b49a3d9 <+20>:    sub    $0x24,%esp
   0x7b49a3dc <+23>:    push   %ebx
   0x7b49a3dd <+24>:    push   $0x4
   0x7b49a3df <+26>:    call   0x7b49a3e0 <GetTickCount+27>
   0x7b49a3e4 <+31>:    add    $0x10,%esp
   0x7b49a3e7 <+34>:    test   %eax,%eax
   0x7b49a3e9 <+36>:    jne    0x7b49a430 <GetTickCount+107>
   0x7b49a3eb <+38>:    mov    $0x989680,%ecx
   0x7b49a3f0 <+43>:    mov    %ecx,%eax
   0x7b49a3f2 <+45>:    imull  -0x20(%ebp)
   0x7b49a3f5 <+48>:    mov    -0x1c(%ebp),%esi
   0x7b49a3f8 <+51>:    mov    %eax,%ecx
   0x7b49a3fa <+53>:    mov    %edx,%ebx
   0x7b49a3fc <+55>:    mov    %esi,%eax
   0x7b49a3fe <+57>:    mov    $0x51eb851f,%edx
   0x7b49a403 <+62>:    imul   %edx
   0x7b49a405 <+64>:    sar    $0x1f,%esi
   0x7b49a408 <+67>:    mov    %edx,%eax
   0x7b49a40a <+69>:    sar    $0x5,%eax
   0x7b49a40d <+72>:    sub    %esi,%eax
   0x7b49a40f <+74>:    cltd   
   0x7b49a410 <+75>:    add    %ecx,%eax
   0x7b49a412 <+77>:    adc    %ebx,%edx
   0x7b49a414 <+79>:    push   $0x0
   0x7b49a416 <+81>:    push   $0x2710
   0x7b49a41b <+86>:    push   %edx
   0x7b49a41c <+87>:    push   %eax
   0x7b49a41d <+88>:    call   0x7b4a8c70 <__udivdi3>
   0x7b49a422 <+93>:    add    $0x10,%esp
   0x7b49a425 <+96>:    lea    -0xc(%ebp),%esp
   0x7b49a428 <+99>:    pop    %ecx
   0x7b49a429 <+100>:    pop    %ebx
   0x7b49a42a <+101>:    pop    %esi
   0x7b49a42b <+102>:    pop    %ebp
   0x7b49a42c <+103>:    lea    -0x4(%ecx),%esp
   0x7b49a42f <+106>:    ret    
   0x7b49a430 <+107>:    sub    $0x8,%esp
   0x7b49a433 <+110>:    push   %ebx
   0x7b49a434 <+111>:    push   $0x1
   0x7b49a436 <+113>:    call   0x7b49a437 <GetTickCount+114>
   0x7b49a43b <+118>:    add    $0x10,%esp
   0x7b49a43e <+121>:    test   %eax,%eax
   0x7b49a440 <+123>:    jne    0x7b49a450 <GetTickCount+139>
   0x7b49a442 <+125>:    mov    $0x989680,%ebx
   0x7b49a447 <+130>:    mov    %ebx,%eax
   0x7b49a449 <+132>:    jmp    0x7b49a3f2 <GetTickCount+45>
   0x7b49a44b <+134>:    lea    0x0(%esi,%eiz,1),%esi
   0x7b49a44f <+138>:    nop
   0x7b49a450 <+139>:    sub    $0x8,%esp
   0x7b49a453 <+142>:    lea    -0x28(%ebp),%eax
   0x7b49a456 <+145>:    push   $0x0
   0x7b49a458 <+147>:    push   %eax
   0x7b49a459 <+148>:    call   0x7b43c360 <NtQueryPerformanceCounter>
   0x7b49a45e <+153>:    mov    -0x28(%ebp),%eax
   0x7b49a461 <+156>:    mov    -0x24(%ebp),%edx
   0x7b49a464 <+159>:    pop    %ecx
   0x7b49a465 <+160>:    pop    %ebx
   0x7b49a466 <+161>:    jmp    0x7b49a414 <GetTickCount+79>
--- snip ---

https://source.winehq.org/git/wine.git/commitdiff/cd215bb49bc240cdce5415c80264f8daa557636a
("kernel32: Use the user shared data to implement GetTickCount().")

--- snip ---
$ gdb mainline-install-5.9-x86_64/lib/wine/kernel32.dll.so -batch -ex
'disassemble GetTickCount-1'

Dump of assembler code for function GetTickCount:
   0x7b4551c0 <+0>:    mov    %edi,%edi
   0x7b4551c2 <+2>:    push   %ebp
   0x7b4551c3 <+3>:    mov    %esp,%ebp
   0x7b4551c5 <+0>:    mov    0x7ffe0320,%eax
   0x7b4551ca <+5>:    pop    %ebp
   0x7b4551cb <+6>:    ret
--- snip ---

https://source.winehq.org/git/wine.git/commitdiff/0c631ebb2354334eaf309bc0765d3283654cf902
("kernel32: Build with msvcrt.")

--- snip ---
$ gdb mainline-install-5.19-x86_64/lib/wine/kernel32.dll -batch -ex
'disassemble GetTickCount'

Dump of assembler code for function KERNEL32!GetTickCount:
   0x7b6257c0 <+0>:    push   %ebp
   0x7b6257c1 <+1>:    mov    %esp,%ebp
   0x7b6257c3 <+3>:    mov    0x7ffe0320,%eax
   0x7b6257c8 <+8>:    pop    %ebp
   0x7b6257c9 <+9>:    ret
--- snip ---

HEAD: wine-5.22-328-g447924a6d68 -> will be included in wine-5.23

https://source.winehq.org/git/wine.git/commitdiff/5a0c9270b1225da86782bffd9eb798a39723d70f
("include: Force aligning stack pointer also for Mingw builds.")

--- snip ---
$ gdb mainline-install-x86_64/lib/wine/kernel32.dll -batch -ex 'disassemble
GetTickCount'

Dump of assembler code for function KERNEL32!GetTickCount:
   0x7b622970 <+0>:    push   %ebp
   0x7b622971 <+1>:    mov    %esp,%ebp
   0x7b622973 <+3>:    and    $0xfffffffc,%esp
   0x7b622976 <+6>:    mov    0x7ffe0320,%eax
   0x7b62297b <+11>:    mov    %ebp,%esp
   0x7b62297d <+13>:    pop    %ebp
   0x7b62297e <+14>:    ret
--- snip ---

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