Hi all,
I have an application that is creating a process suspended and then using detours modifies the imports of the new process prior to resuming it (the application is called Tracker.exe and is part of MS toolchain, it can be retrieved in MS EWDK package)
The application does not work as it should on Wine, as the DLL its trying to inject to the new process is not getting loaded, I tracked down the problem here are the technical details:
When a new process is created, after all the other set-ups its running the function: dlls/ntdll/server.c!server_init_process_done
This function sets up the handlers for the different signals (signal_init_process) and makes a wine_server_call init_process_done.
In the wine server function server/process.c!init_process_done a check is made to see if the thread of the process needs to be suspended (stop_thread_if_suspended) and indeed when a process is created with the CREATE_SUSPENDED flag, thread->suspend == 1, process->suspend == 0, and the process state is done at this point).
This makes the wine_server call to stop_thread which will send a SIGUSR1 signal to the new process.
The new process however still have the signals in a block state, thus not processing the signal and putting it into a pending state.
The next thing that happens is LdrInitializeThunk continues and fixing up the EXE module imports, this is not the same behavior as Windows in which the Ldr only starts running after the thread has resumed.
Only later signals are being unblocked and then the thread enters a suspended state, the function which unblocks the signals today is attach_process_dlls
The interesting thing is that in the past Wine behavior was correct and the change that basically broke it is commit:
commit 0f5fc117a2320bb7e21b9ae4d07d717bed413171 Author: Alexandre Julliard julliard@winehq.org Date: Mon Nov 19 14:27:07 2007 +0100
ntdll: Unblock signals in process init only after the dlls have been imported.
Unfortunately though there I could not find any reason why the change was made or if there is any bug that it fixed back then (2007) .
I was thinking that perhaps in order to resolve the problem and be closer in the behavior to Windows would be to unblock the signals just before server_init_process_done returns.
Please let me know if you have any other questions, will be happy to resolve this now that we have all the information laid out.
Thanks, -- Jon.
Jon Doron arilou@gmail.com writes:
The interesting thing is that in the past Wine behavior was correct and the change that basically broke it is commit:
commit 0f5fc117a2320bb7e21b9ae4d07d717bed413171 Author: Alexandre Julliard julliard@winehq.org Date: Mon Nov 19 14:27:07 2007 +0100
ntdll: Unblock signals in process init only after the dlls have
been imported.
Unfortunately though there I could not find any reason why the change was made or if there is any bug that it fixed back then (2007) .
There were apps (usually copy protection) that expected to find some dlls already loaded in order to patch them. Still, it's very possible that the initialization order isn't quite correct yet. The first step would be to write some test cases.
Sure what type of tests would you like to see? One thing to note is the application I'm referring to Tracker which is part of MS toolchain is a Microsoft application, so no hacks or anything that copy protection software did that sometimes was not fully compatible with all the loaders changes MS did through out the years.
On Fri, Aug 25, 2017 at 4:41 PM, Alexandre Julliard julliard@winehq.org wrote:
Jon Doron arilou@gmail.com writes:
The interesting thing is that in the past Wine behavior was correct and the change that basically broke it is commit:
commit 0f5fc117a2320bb7e21b9ae4d07d717bed413171 Author: Alexandre Julliard julliard@winehq.org Date: Mon Nov 19 14:27:07 2007 +0100
ntdll: Unblock signals in process init only after the dlls have
been imported.
Unfortunately though there I could not find any reason why the change was made or if there is any bug that it fixed back then (2007) .
There were apps (usually copy protection) that expected to find some dlls already loaded in order to patch them. Still, it's very possible that the initialization order isn't quite correct yet. The first step would be to write some test cases.
-- Alexandre Julliard julliard@winehq.org
Jonathan Doron jond@wizery.com writes:
Sure what type of tests would you like to see?
Basically you'd create a suspended process and then poke around and test what has or hasn't been initialized yet. You can use the various things that the Wine loader does during init as a guide to what to test. Then you can also try changing things, resume the process and check that it has the expected effect.