Windows Subsystem For Linux (new techonology in Win10) uses LxssUserSession service. This service is undocumented, but it is used as API for WSL (bash.exe uses this service to run ELFs). As i can see, it is part of COM: There is CLSID record in registry that has AppID. And AppID has LocalService record: LxssUserSession.
I am not familiar with COM, but if I understand it correctly, there should be COM component backed by this service. I am not able to create instance of this COM from script since there is no ProgID, but I tried to instantiate it using OleView. How ever, it reports that CoCreateInstance returned error. How to debug this error? Could it be that COM component can't be created and used for something different (i.e. there is some other interface). Is it generally possible to work with undocumented COM component? Can I trace bash.exe calls to this service (something like logger.exe or ltrace but for COM?)
Some background:
Here is error I am getting: http://s32.postimg.org/wpthro5kl/error.png
bash.exe != /bin/bash. bash.exe is PE (Win64 bin app) that connects to LxssUserSession and asks it to run /bin/bash (which is ELF (linux app!). bash.exe is better be called "WLS.exe", but for some reason they called it bash.exe.
Please see here: https://msdnshared.blob.core.windows.net/media/2016/04/LXSS-diagram-1024x472.jpg and here is its headers http://s32.postimg.org/khjjf81th/bash.png .
So, I am sure bash.exe uses COM to connect to LxssUserSession and LxssUserSession uses Pico (Psp..) functions to launch ELF as "pico process" (See here https://blogs.msdn.microsoft.com/wsl/2016/04/22/windows-subsystem-for-linux-overview/).
Both are undocumented, but I believe I can use COM some how, but I am getting error which I provided as first link:(
I was able to instantiate object using OleView by setting default impersonation level to "Impersonate" in component services config (you may need to reboot). I can see ILxssSession interface now. But since there is not IDispatch and no TLB, there is nothing I can do: methods are unknown to me(
I just doing the same kind of project. What I do is reverse engineering "bash.exe" to see how it work. Currently, I can create an insurance of LxssUserSession and call some method in it. But it still not complete. You can find it source here.
Related
I want to create a Windows system service using QT/MinGW which communicates with other applications over DBUS (from freedesktop.org). For the moment DBUS is running as a "service" by meaning of it was installed as service using the instsrv/srvany tools (however, the DBUS will get it's bus-service-win later). Since running as a service, DBUS is running as system bus.
I wrote a simple application to ensure that DBUS is working (creates on simple object with 1 method and exectued it with QDBusViewer). Well, that worked.
Next I tried to use the same DBUS stuff in the ServiceMain from my service, where ServiceMain is a member of a class created by our own). I can see the object in QDBusViewer, but as soon as I select it, QDBusViewer reported a timeout (no reply) after it stucked for a while.
I have seen this behavior in my test application, and could fix it by creating a QCoreApplication "app" and "block" on app.exec() after the DBus object have been created. I tried the same in the service, but got a warning that QCoreApplication was not created in the main thread, and the problem still persists.
I tried to create "app" in the function that calls StartServiceControlDispatcher() and run app.exec in the ServiceMain, but app.exec() quits immediately with a the error "must be called from the main thread".
How can I get over this? Have much thanks in before.
Comparing my own service class against the QtService class from "QT Solution" fixed my problem.
All after all I needed to put the StartServiceControlDispatcher() function into a QThread and change the method of my service class in a way that exec() is only executed when definitely running in the context of the SCM.
I'm using WatiN in a console application. I set platform to x86, and I added [STAThread] to my Main. I confirmed that the application is actually running in 32-bit mode (which WatiN requires).
WatiN works fine when testing locally, but crashes when running on AppHarbor:
[COMException: Retrieving the COM class factory for component with CLSID {0002DF01-0000-0000-C000-000000000046} failed due to the
following error: 80080005 Server execution failed (Exception from
HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).]
0007FFB8B2184B3 WatiN_Core!WatiN.Core.IE.CreateNewIEAndGoToUri(System.Uri,
WatiN.Core.Interfaces.IDialogHandler, Boolean)+0x103
How can I get WatiN working on AppHarbor?
To be able to run WatIn it need to have access (as an administrator) to some resources. When you run a COM object it needs to be able to query the registry to find out if Internet Explorer is a COM object in that system and if it is launch it. I don't have first hand experience with AppHarbor but I'm pretty sure they won't allow you to be able to query what COM servers their machines have so they won't provide you with that access.
To be 100% sure about this you should ask them if you can have access to query COM objects on their machines.
When you run it on your local machine that works because either you are logged in as an admin or you are launching the process as an admin.
Hope this helps.
I have compiled a program on Windows Server 2008 using GHC 7.6.3 32-bit. I'm attempting to run it via a service within windows on boot-up (and ideally keep it up). To do so I have created a service with the following command successfully
sc create stworker binPath= "C:\Users\vagrant\Desktop\worker.exe"
The problem I'm having is that when I attempt to start the service I receive the following error (see image below).
The executable runs fine when I double click it. So not sure why Windows wouldn't allow the service to be run.
I don't think this is an issue w/ GHC. I'm under the assumption that GHC compiles to native code and not MSIL.
So any ideas why I can't run my executable as a service?
As mentioned in the comments, you need to actually implement the Win32 service API for your program to behave as a Windows service, and you can do this using the Win32-services package.
There's also a wrapper package Win32-services-wrapper that I wrote that aims to provide some of the boilerplate and handle logging, so that defining a service looks like this:
main =
defineService $
Service {
serviceName = "Service",
-- Start the service given a debug handle to write to.
-- Make sure not to use stdout or stderr as they don't exist.
-- Any state needed by serviceStop can be returned here -
-- the Service type takes the type of the state as a type parameter
serviceStart = \debugHandle -> ...,
-- Stop the service given the service state returned by serviceStart
serviceStop = \serviceState -> ...
}
There's a real example of using it in darcsden.
I have a Windows executable that is launched from within a service by calling CreateProcessWithLogonW() with a set of specfied user details.
This works fine and the process starts as expected. However, when this process tries to launch other processes itself, currently just using CreateProcess() these start then die straight away - they are executables that require desktop access.
After reading up on Microsoft's article on CreateProcess() - http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx
I think can see why this is happening and it makes sense to an extent. CreateProcess() knows the calling process is impersonating a user so it uses it's parent process, which in this case is the Local System account. But of course anything run in the local system account doesn't have the access we need, so the launched process dies.
Oddly when I was previously using LogonUser() and CreateProcessAsUser() to launch the initial executable within the service, it worked fine. But I had to change this to CreateProcessWithLogonW() due to problems with not having the correct privileges.
Does anybody know of a solution to this? I've seen talk about this elsewhere on the web but not with any definite solution. It seems like I possibly need the token of the user i'm logging on with in CreateProcessWithLogonW() with so I can use it to launch the other processes later? But I have no way of getting hold of this token, can this be retreived for the current user in any way?
Any help would be greatly appreciated, thanks :)
We solved the problem using some code that I found long-ago. The "copyright" section of one of the source modules contains the following:
/////////////////////////////////////////////////////////////
// CreateProcessAsUser.cpp
//
// Written by Valery Pryamikov (1999)
//
// Command line utility that executes a command under specified user identity
// by temporarily installing itself as a service.
//
// Based on Keith Brown's AsLocalSystem utility (http://www.develop.com/kbrown)
// Uses some code from Mike Nelson's dcomperm sample utility
// and from tlist sample (Microsoft Source Code Samples)
//
// Use:
// CreateProcessAsUser.exe [-i[nteractive]]|[-s[ystem]]|
// [-u"UserName" -d"DomainName" -p"Password"]|[-a"AppID"] command
// Command must begin with the process (path to the exe file) to launch
// -i process will be launched under credentials of the
// "Interactive User" (retrieved from winlogon\shell process)
// -a process will be launched under credentials of the user
// specified in "RunAs" parameter of AppID.
// -s process will be launched as local system
// -u -d -p process will be launched on the result token of the
// LogonUser(userName,domainName,password,LOGON32_LOGON_BATCH...)
//
// either (-s) or (-i) or (-a) or (-u -d -p) parameters must supplied
//
// Examples:
// CreateProcessAsUser -s cmd.exe
// CreateProcessAsUser -a"{731A63AF-2990-11D1-B12E-00C04FC2F56F}" winfile.exe
//
/////////////////////////////////////////////////////////////
Perhaps this information will yield hits within your Google searches - I attempted a few quick attempts but came up empty-handed.
We decomposed the internals into a set of API that yielded the results we needed.
Do you own the code launched using CreateProcessWithLogonW (and which in turn calls CreateProcess)? If you do not then you might need to perform IAT (or API) hooking on it (i.e. at run-time), as to substitute any calls to CreateProcess with an appropriate procedure that also uses CreateProcessWithLogonW or CreateProcessWithTokenW. See APIHijack, Detours.
After this is done, the child process may require access to HKCU. If you are not already doing this, you should load the profile of each impersonated user, once per user, before calling CreateProcessWithLogonW.
By default, CreateProcessWithLogonW
does not load the specified user
profile into the HKEY_USERS registry
key. This means that access to
information in the HKEY_CURRENT_USER
registry key may not produce results
that are consistent with a normal
interactive logon. It is your
responsibility to load the user
registry hive into HKEY_USERS before
calling CreateProcessWithLogonW, by
using LOGON_WITH_PROFILE, or by
calling the LoadUserProfile function.
Isn't there an option for services to allow them to interact with the desktop? If setting that option for your service is a possibility, that would probably be the simplest solution.
I'm assuming that this process is a service; that isn't specified in the question, but seems logical given that it is running as Local System account.
Where you're getting stuck isn't in CreateProcess, It's in CreateService. If you want your service to be able to interact with the desktop, you have to specify SERVICE_INTERACTIVE_PROCESS as one of the flags to the argument dwServiceType. This setting is inherited by child processes of the service.
You can also modify an existing service's setting by using the Services tool, select Properties for the service, click on the "Log On" tab, and select the check box "Allow service to interact with desktop".
I have an installation package that installs a service process that I create. I'd like to prompt the user for the username/password of the account that the service process should run under. I'd like to verify the the username/password combination are valid before continuing with the installation. I have a C DLL that I am using for special installation behavior, but I can't figure out how to use the Windows API to verify an account's credentials. I'd like to be able to support the same account name syntax used by the service control manager.
The function you want to use is LogonUser. You can even be extra-cool and specify the LOGON32_LOGON_SERVICE flag which checks to make sure the user has the appropriate permissions to run a service.
LogonUser is the canonical way to do this, though Microsoft somewhat discourages it.
I've implemented this using the LogonUser function as you guys have mentioned (by the way, this service requires WinXP SP2 or later so I'm not worried about the privilege issue). However, this isn't quite working as I had hoped. If I call QueryServiceConfig, lpServiceStartName is in the format ".\accountname". If I pass this string as is to LogonUser, it fails. I assume the portion before the '\' represents the machine on which the user belongs?
Also, if I call ChangeServiceConfig specifying "LocalSystem" and "" for the lpServiceStartName and lpPassword parameters respectively, this works fine. However, calling LogonUser with these parameters does not work.
I'd really like to use the same syntax that the SCM uses for the account names.