https://bugs.winehq.org/show_bug.cgi?id=47052
Bug ID: 47052
Summary: MRAC Anti-Cheat (
My.Com Warface) fails to start game
process, 'ntoskrnl.exe.ObReferenceObjectByHandle'
fails to lookup event handles created by MRAC service
process
Product: Wine
Version: 4.6
Hardware: x86-64
OS: Linux
Status: NEW
Severity: normal
Priority: P2
Component: wineserver
Assignee: wine-bugs(a)winehq.org
Reporter: focht(a)gmx.net
Distribution: ---
Hello folks,
as it says. Continuation of bug 47044 , bug 47047 , bug 37355 ...
--- snip ---
$ pwd
/home/focht/.wine/drive_c/users/focht/Local Settings/Application
Data/GameCenter
$ WINEDEBUG=+seh,+loaddll,+process,+ntoskrnl,+ntdll,+relay,+server wine
./GameCenter.exe >>log.txt 2>&1
...
0009:Call KERNEL32.CreateProcessW(00000000,0a0a782c L"\"C:\\users\\focht\\Local
Settings\\Application Data\\GameCenter\\GameCenter.exe\" -job=2_8
-job_pipe=GameCenterV5_AAE21A18E0399D09F3AAF4874C40186E
-job_hint=GCJobGameLaunch",00000000,00000000,00000000,01000000,00000000,00000000,0033f0b8,0033f0a8)
ret=00435f19
...
0009:trace:process:CreateProcessInternalW starting L"C:\\users\\focht\\Local
Settings\\Application Data\\GameCenter\\GameCenter.exe" as Win32 binary
(400000-da1000, x86)
...
0009:trace:process:CreateProcessInternalW started process pid 00c8 tid 00c9
...
--- snip ---
MRAC service start:
--- snip ---
...
00cd:Call KERNEL32.CreateProcessW(00000000,00022e50
L"C:\\windows\\System32\\mracsvc.exe",00000000,00000000,00000000,00000400,00340000,00000000,00aaf130,00aaf000)
ret=7fe720baedc6
00cd:trace:process:CreateProcessInternalW starting
L"C:\\windows\\System32\\mracsvc.exe" as Win64 binary (140000000-14106f000,
x86_64)
00cd: *fd* 39 <- 714
00cd: new_process( inherit_all=0, create_flags=00000400, socket_fd=39,
exe_file=0178, access=001fffff, cpu=x86_64, info_size=616,
objattr={rootdir=0000,attributes=00000000,sd={},name=L""}, info={... )
00cd: new_process() = 0 { info=017c, pid=00ce, handle=0180 }
00cd: new_thread( process=0180, access=001fffff, suspend=0, request_fd=-1,
objattr={rootdir=0000,attributes=00000000,sd={},name=L""} )
00cd: *fd* 0244 -> 716
...
00d7: init_thread( unix_pid=30363, unix_tid=30371, debug_level=1,
teb=7fffffe8c000, entry=7bcbd070, reply_fd=36, wait_fd=38, cpu=x86_64 )
00d7: init_thread() = 0 { pid=00ce, tid=00d7, server_start=1d4f7628a8ec3a2
(-43.8978330), info_size=0, version=580, all_cpus=00000003, suspend=0 }
...
--- snip ---
MRAC service opening MRAC Anti-Cheat kernel service/driver:
NOTE: I've rearranged the log output in sequential request order to be more
readable. Trace messages from follow-up IOCTL issued by service process
overlapped/interleaved with kernel driver still processing IRP_MJ_CREATE.
--- snip ---
...
00d7:Call KERNEL32.CreateFileW(1400718a0
L"\\\\.\\mracdrv",00000000,00000003,00000000,00000003,00000000,00000000)
ret=14000b3f3
00d7:trace:ntdll:FILE_CreateFile handle=0x98e868 access=00100080
name=L"\\??\\mracdrv" objattr=00000040 root=(nil) sec=(nil) io=0x98e880
alloc_size=(nil) attr=00000000 sharing=00000003 disp=1 options=00000060
ea=(nil).0x00000000
00d7: open_file_object( access=00100080, attributes=00000040, rootdir=0000,
sharing=00000003, options=00000060, filename=L"\\??\\mracdrv" )
00dd: *wakeup* signaled=1
00d7: open_file_object() = 0 { handle=00a4 }
00dd:Ret KERNEL32.WaitForMultipleObjectsEx() retval=00000001 ret=7f489a8c8c46
00d7:Ret KERNEL32.CreateFileW() retval=000000a4 ret=14000b3f3
00dd: get_next_device_request( manager=0030, prev=0000, status=00000103 )
00dd: get_next_device_request() = 0 {
params={major=CREATE,access=00100080,sharing=00000003,options=00000060,device=00031e00},
next=0044, client_tid=0000, client_thread=00000000, in_size=0, out_size=0,
next_data={} }
...
00dd:trace:ntoskrnl:dispatch_create device 0x31e00 -> file 0x31f70
...
00dd:trace:ntoskrnl:IoAllocateIrp 1, 0
...
00dd:trace:ntoskrnl:IoInitializeIrp 0x32040, 280, 1
00dd:Call driver dispatch 0x1400291d4 (device=0x31e00,irp=0x32040)
...
00dd:Call ntoskrnl.exe.IofCompleteRequest(00032040,00000000) ret=140011ce1
...
00dd:trace:ntoskrnl:IofCompleteRequest 0x32040 0
00dd:trace:ntoskrnl:IoCompleteRequest 0x32040 0
00dd:trace:ntoskrnl:IoCompleteRequest calling 0x7f489a8c6330( 0x31e00, 0x32040,
0x44 )
00dd: set_irp_result( handle=0044, status=00000000, size=0, file_ptr=00031f70,
data={} )
00dd: set_irp_result() = 0
00dd:trace:ntoskrnl:IoCompleteRequest CompletionRoutine returned 0
00dd:trace:ntoskrnl:IoFreeIrp 0x32040
...
00dd:Ret ntoskrnl.exe.IofCompleteRequest() retval=00000001 ret=140011ce1
...
00dd:Ret driver dispatch 0x1400291d4 (device=0x31e00,irp=0x32040)
retval=00000000
...
--- snip ---
MRAC service creates an event and passes the handle to the MRAC Anti-Cheat
kernel service/driver via private IOCTL:
--- snip ----
...
00d7:Call KERNEL32.CreateEventW(00000000,00000001,00000000,00000000)
ret=14000b42c
00d7:Call ntdll.NtCreateEvent(0098e998,001f0003,0098e9b0,00000000,00000000)
ret=7b4a76e3
00d7: create_event( access=001f0003, manual_reset=1, initial_state=0,
objattr={rootdir=0000,attributes=00000080,sd={},name=L""} )
00d7: create_event() = 0 { handle=00a8 }
00d7:Ret ntdll.NtCreateEvent() retval=00000000 ret=7b4a76e3
00d7:Ret KERNEL32.CreateEventW() retval=000000a8 ret=14000b42c
...
00d7:Call rpcrt4.RpcImpersonateClient(00000000) ret=14000b450
...
00d7:Call advapi32.ImpersonateNamedPipeClient(00000078) ret=7fee32a7e672
...
00d7:trace:ntdll:NtFsControlFile
(0x78,(nil),(nil),(nil),0x98e880,0x0011001c,(nil),0x00000000,(nil),0x00000000)
...
00d7:fixme:ntdll:NtFsControlFile FSCTL_PIPE_IMPERSONATE: impersonating self
00d7:trace:ntdll:RtlImpersonateSelf (00000002)
00d7:trace:ntdll:NtOpenProcessTokenEx
(0xffffffffffffffff,0x00000002,0x00000000,0x98e5b0)
...
00d7: open_token( handle=ffffffff, access=00000002, attributes=00000000,
flags=00000000 )
00d7: open_token() = 0 { token=00ac }
...
00d7:trace:ntdll:NtDuplicateToken (0xac,0x00000004,{name=<null>,
attr=0x00000000, hRoot=(nil), sd=(nil)}
,0x00000002,0x00000002,0x98e5b8)
...
00d7: duplicate_token( handle=00ac, access=00000004, primary=0,
impersonation_level=2,
objattr={rootdir=0000,attributes=00000000,sd={},name=L""} )
...
00d7: duplicate_token() = 0 { new_handle=00b0 }
...
00d7: set_thread_info( handle=fffffffe, mask=4, priority=0, affinity=00000000,
entry_point=00000000, token=00b0 )
00d7: set_thread_info() = 0
...
00d7: close_handle( handle=00b0 )
00d7: close_handle() = 0
...
00d7: close_handle( handle=00ac )
00d7: close_handle() = 0
00d7:Ret advapi32.ImpersonateNamedPipeClient() retval=00000001
ret=7fee32a7e672
00d7:Ret rpcrt4.RpcImpersonateClient() retval=00000000 ret=14000b450
...
00d7:Call
KERNEL32.DeviceIoControl(000000a4,81002200,0006d250,00000096,0098eba0,00000004,0098ec28,00000000)
ret=14000b5b4
...
00d7:trace:ntdll:NtDeviceIoControlFile
(0xa4,(nil),(nil),(nil),0x98e9d0,0x81002200,0x6d250,0x00000096,0x98eba0,0x00000004)
...
00d7: ioctl( code=81002200,
async={handle=00a4,event=0000,iosb=0098e9d0,user=0006c120,apc=00000000,apc_context=00000000},
in_data={66,00,00,00,00,00,00,00,a8,00,00,00,00,00,00,00,5c,00,3f,00,3f,00,5c,00,43,00,3a,00,5c,00,4d,00,79,00,47,00,61,00,6d,00,65,00,73,00,5c,00,57,00,61,00,72,00,66,00,61,00,63,00,65,00,20,00,4d,00,79,00,2e,00,43,00,6f,00,6d,00,5c,00,42,00,69,00,6e,00,33,00,32,00,52,00,65,00,6c,00,65,00,61,00,73,00,65,00,5c,00,47,00,61,00,6d,00,65,00,2e,00,65,00,78,00,65,00,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00}
)
00d7: ioctl() = PENDING { wait=00ac, options=00000060, out_data={} }
...
00d7: select( flags=2, cookie=0098e3dc, timeout=infinite, prev_apc=0000,
result={}, data={WAIT_ALL,handles={00ac}} )
00d7: select() = PENDING { timeout=infinite, call={APC_NONE}, apc_handle=0000 }
...
--- snip ---
MRAC Anti-Cheat kernel service/driver processes the IOCTL which contains the
sync event and the process name to be started as unicode string.
66,00,00,00,00,00,00,00 -> buflen
a8,00,00,00,00,00,00,00 -> handle
00,5c,00,3f ... -> \??\C:\MyGames\Warface My.Com\Bin32Release\Game.exe
--- snip ---
...
00dd: get_next_device_request( manager=0030, prev=0000, status=00000000 )
00dd: get_next_device_request() = 0 {
params={major=DEVICE_CONTROL,code=81002200,file=00031f70}, next=0044,
client_tid=00d7, client_thread=00000000, in_size=150, out_size=4,
next_data={66,00,00,00,00,00,00,00,a8,00,00,00,00,00,00,00,5c,00,3f,00,3f,00,5c,00,43,00,3a,00,5c,00,4d,00,79,00,47,00,61,00,6d,00,65,00,73,00,5c,00,57,00,61,00,72,00,66,00,61,00,63,00,65,00,20,00,4d,00,79,00,2e,00,43,00,6f,00,6d,00,5c,00,42,00,69,00,6e,00,33,00,32,00,52,00,65,00,6c,00,65,00,61,00,73,00,65,00,5c,00,47,00,61,00,6d,00,65,00,2e,00,65,00,78,00,65,00,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00}
}
00dd:trace:ntoskrnl:dispatch_ioctl ioctl 81002200 device 0x31e00 file 0x31f70
in_size 150 out_size 4
00dd:trace:ntoskrnl:IoBuildDeviceIoControlRequest 81002200, 0x31e00, 0x26740,
150, 0x26740, 150, 0, (nil), (nil)
00dd:trace:ntoskrnl:IoAllocateIrp 1, 0
...
00dd:trace:ntoskrnl:IoInitializeIrp 0x32040, 280, 1
...
00dd:Call driver dispatch 0x1400291d4 (device=0x31e00,irp=0x32040)
...
00dd:Call
ntoskrnl.exe.ObReferenceObjectByHandle(000000a8,00000002,7f489a919330,00000000,0043f5e0,00000000)
ret=1400125d4
00dd:trace:ntoskrnl:ObReferenceObjectByHandle 0xa8 2 0x7f489a919330 0 0x43f5e0
(nil)
00dd: get_kernel_object_ptr( manager=0030, handle=00a8 )
00dd: get_kernel_object_ptr() = INVALID_HANDLE { user_ptr=00000000 }
00dd:Ret ntoskrnl.exe.ObReferenceObjectByHandle() retval=c0000008
ret=1400125d4
00dd:Call ntoskrnl.exe.IofCompleteRequest(00032040,00000000) ret=140012665
00dd:trace:ntoskrnl:IofCompleteRequest 0x32040 0
00dd:trace:ntoskrnl:IoCompleteRequest 0x32040 0
00dd:trace:ntoskrnl:IoCompleteRequest calling 0x7f489a8c6330( 0x31e00, 0x32040,
0x44 )
00dd: set_irp_result( handle=0044, status=c0000008, size=0, file_ptr=00031f70,
data={} )
00d7: *wakeup* signaled=192
00dd: set_irp_result() = 0
00dd:trace:ntoskrnl:IoCompleteRequest CompletionRoutine returned 0
00d7: select( flags=2, cookie=0098e3dc, timeout=infinite, prev_apc=0000,
result={}, data={WAIT_ALL,handles={00ac}} )
...
00d7: select() = USER_APC { timeout=infinite,
call={APC_ASYNC_IO,user=0006c120,sb=0098e9d0,status=INVALID_HANDLE},
apc_handle=00b0 }
...
00dd:trace:ntoskrnl:IoFreeIrp 0x32040
...
00dd:Ret ntoskrnl.exe.IofCompleteRequest() retval=00000001 ret=140012665
...
00d7: select( flags=2, cookie=0098e3dc, timeout=infinite, prev_apc=00b0,
result={APC_ASYNC_IO,status=INVALID_HANDLE,total=0},
data={WAIT_ALL,handles={00ac}} )
...
00d7: select() = 0 { timeout=infinite, call={APC_NONE}, apc_handle=0000 }
...
00d7:Ret KERNEL32.DeviceIoControl() retval=00000000 ret=14000b5b4
...
00d7:Call KERNEL32.GetLastError() ret=14000b5cb
...
00d7:Ret KERNEL32.GetLastError() retval=00000006 ret=14000b5cb
...
00d7:Call rpcrt4.RpcRevertToSelfEx(00000000) ret=14000b5e4
...
00d7:Call advapi32.RevertToSelf() ret=7fee32a7e74d
00dd:Ret driver dispatch 0x1400291d4 (device=0x31e00,irp=0x32040)
retval=c0000008
...
00c9:Call KERNEL32.WideCharToMultiByte(0000fde9,00000000,00e4825c L"Message:
20.04.2019 12:20:14.415 200.201 [TJobClient] GameLaunch: CreateProcess
ErrorCode=0x00000006 ProcessHandle=0x00000000
ProcessId=0\r\n",0000008b,09bcfdac,000001a2,00000000,00000000) ret=0040c31c
--- snip ---
This obviously can't work since the requestor (winedevice hosting process for
the MRAC kernel driver) is not the process which created the handle (MRAC
service process).
The methodology to pass usermode process created handles to drivers is pretty
much text book. For reference, one of the Microsoft Windows driver examples
which essentially does the same thing:
https://github.com/Microsoft/Windows-driver-samples/tree/master/general/eve…
Specifically:
https://github.com/Microsoft/Windows-driver-samples/blob/master/general/eve…
--- quote ---
...
The purpose of this sample is to demonstrate how a kernel-mode driver can
notify
an user-app about a device event. There are several different techniques.
This sample
will demonstrate two very commonly used techniques.
1) Using an event:
The application creates an event object using CreateEvent().
The app passes the event handle to the driver in a private IOCTL.
The driver is running in the app's thread context during the IOCTL so
there is a valid user-mode handle at that time.
The driver dereferences the user-mode handle into system space & saves
the event object pointer for later use.
The driver signals the event via KeSetEvent() at IRQL <=
DISPATCH_LEVEL.
The driver deletes the references to the event object.
--- snip ---
$ sha1sum WarfaceMycomLoader_805e0da40d16630c2fe73ed12399cb48_.exe
b07e87a029d6697ad823dc03fdbf297c406a91b9
WarfaceMycomLoader_805e0da40d16630c2fe73ed12399cb48_.exe
$ du -sh WarfaceMycomLoader_805e0da40d16630c2fe73ed12399cb48_.exe
6.8M WarfaceMycomLoader_805e0da40d16630c2fe73ed12399cb48_.exe
$ wine --version
wine-4.6-61-g085e58878f
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.