I always set my drivers Imagepath directly.(C:\Windows\System32\drivers\abc.sys)
But I just knew many device drivers set their ImagePath to %SystemRoot%\system32\svchost.exe -k netsvcs
This is Lanmanworkstation driver's registry hive.
I guess Lanmanworkstation driver's image file is mrxsmb.sys
But they didn't put 'System32\drivers\mrxsmb.sys'. Why.
What does svchost.exe -k netsvcs mean?
Even though there is no certain path, StartService function works well.
How does Service Manager(? i'm not sure) find the driver's image path?
Is there an advantage using this?
What if I decide to use this way, are there my driver codes should modify?
You are confusing between device drivers and services.
svchost.exe is used to share the same process between multiple services. The implementation is internal to Windows so use outside of Windows is not supported.
If you write a device driver (for hardware, or a filter driver) or do not work for Microsoft, you cannot use svchost.
The reason for the confusion is because old style (NT4), non-plug-and-play drivers can be started using the Service Control Manager APIs.
svchost is a host process for other services, contained in DLLs. The part after the "-k" indicates the service group. You can find the service DLL path in HKLM\System\CurrentControlSet\Services\LanmanWorkstation\Parameters in the ServiceDll value. I'm guessing the reason it still starts correctly if you remove the image path is because the service type is set to SERVICE_WIN32_SHARE_PROCESS, and the SCM probably ignores the image path (not sure about this).
svchost.exe is a "multi-purpose" service. It incorporates multiple services in one single exe file, each of which can be seperately controlled using e.g. services management console. The parameters to svchost.exe states the "subservice" inside the exe file.
As startService() is not a control message to the service itself but instead only the request to start a certain executable (which itself must "know" that it is a service (and wich service) and will then register with service control manager), windows will simply execute the binary that ImagePath points to.
In this case (LanManWorkstation) this binary is svchost.exe, the parameter given to it is -k netsvc. This lets svchost.exe know which of the many service it provides should be started.
As usual, the binary doesn't need to contain all the function in itself but can also load additional libraries. mrxsmb.sys may well be such a library, though I'm not sure of this point.
So this answer is more of a "how does it work in general" than a "yes, netsvc and mrxsmb.sys are LanManWorkstation".
Related
I have implemented a class that gets local printers and, depending on the application option, uses one of the local printer available.
Firstly, the class enumerates the printers (EnumPrinters - PRINTER_ENUM_LOCAL) and saves the corresponding PRINTER_INFO_2. Then, it gets printer capabilities (DeviceCapabilites) and DEVMODE. Each class instance will access one printer.
When application selects the printing option, it selects which printer will be used and its corresponding instance of the class. Then, this instance creates the device context:
m_hdc = CreateDC (m_pi2->pDriverName, m_pi2->pPrinterName, NULL, m_pdm));
where
HDC m_hdc;
PRINTER_INFO_2 * m_pi2;
DEVMODE * m_pdm;
and process all printing data accordingly.
The problem is that sometimes, the CreateDC return NULL and GetLastError() return ERROR_FILE_NOT_FOUND(2).
I mean 'sometimes' because in other machines, with same printer, same processor, same Windows XP SP3 image and same test data, the CreateDC processes correctly. In addition, the reinstalling the system and application the problem disappears sometimes no.
I am looking forward to hearing any suggestion that helps me to find out the issue.
Thank you in advance.
It sounds like a problem loading a file required by the printer driver. You could use Process Monitor (a free SysInternals tool downloadable from microsoft.com) to get a bunch of information about what's going on at the time of the error. I'd do a capture and look at failed file and registry accesses. The fact that it fails intermittently on one particular machine seems consistent with a messed up driver configuration.
Another thing you could try is to create an information context rather than a device context. You can't print with an IC, but you can query information about the device, which may be a way to get additional information.
I have a network critical Windows 7 service. It must start before any network related service on the system, or that network service may fail. My service requires that Winsock is fully initialized by the time it runs.
How can I coerce Windows to load my service at the appropriate time? i.e. Immediately after Winsock is available.
I used the LoadOrder utility by MS Sysinternals. Found out the group should be "NetworkProvider". Also, since the loader loads in lexicographical alphabetical order, I named my process prefixing "Z" so it will load last in the "NetworkProvider" LoadOrderGroup.
You can make your service depend on other services using the depends option. To make other services dependent on your service, you'd need to set their dependencies.
I have a COM server LocalServer32 EXE started when a client application calls c_com_ptr::CreateInstance (using ATL wrappers.)
On Windows 7, when a second client application running under the same user account also calls c_com_ptr::CreateInstance, a second copy of the EXE is launched running under the same user account. I was under the impression, from a past life, that the second client would share the first EXE.
Is the LocalServer32 process shared, or not? When, or when not? Googling for an answer gives me a huge noise to signal ratio and I can't find the answer.
My CLSID registry key has the LocalServer32 value giving the EXE path, ProgID, Programmable (empty string), TypeLib (GUID), and a VersionIndependentProgId. I have an AppID key.
I do not want to run the EXE as a service, and I don't mind that the process is not shared. I just want to know the rules so I know what to expect (on Windows Server 2003 onwards.)
EDIT: Following Chris' answer below, I examined the CoRegisterClassObject call in my server. I'm using ATL, and I overrode MyServer::RegisterClassObjects to hook into the calling chain to CAtlExeModuleT::RegisterClassObjects and see that ATL is using CLSCTX_LOCAL_SERVER and REGCLS_MULTIPLEUSE.
Changing this to CLSCTX_LOCAL_SERVER and REGCLS_SINGLEUSE causes more processes to be started, depending on the number of COM objects created by the client, as expected.
Still, going back to REGCLS_MULTIPLEUSE, I get one COM server process per COM client process, each server process containing all of the COM objects for its client, as expected, except that if two COM clients are running under the same user account, they each get their own server which is not how I understood REGCLS_MULTIPLEUSE.
Could the difference be that the clients themselves are actually Windows services? (They are.) When a Windows service process running as a user account creates a COM object under REGCLS_MULTIPLEUSE, is this treated differently, causing the observed behavior? Why am I getting more than one process? (And just to clarify, I do not want my COM server to run as a Windows service, but the clients that use it do run as Windows services.)
Also, running the clients as either Local System, or Network Service, REGCLS_MULTIPLEUSE works as I would have expected: only a single COM server EXE process is started. The multiple processes are started when the COM clients are Windows services running under user accounts.
The routing of out-of-process activation requests is controlled by the registration of class objects with the COM Service Control Manager. If the SCM has a usable registered class object, that will be used to service the request. If it doesn't, it will start an exe process instance of the COM server to get one. Whether multiple activation requests are routed to a single COM server exe process therefore depends on the following factors at least (I'm not sure if this is a complete list):
the activation flags specified by the COM server when it calls CoRegisterClassObject to register with the SCM can cause future activation requests to result in a new exe process instance being started, the simplest and commonest case being the use of the flag REGCLS_SINGLEUSE, which allows the registered class object to be used for a single activation only.
Depending on how the class is registered, activation requests from different security contexts may be serviced by different COM server exe instances (it seems this won't apply in your scenario as your client applications run under the same security contexts).
I would like to improve the way how an application is checking that another instance is not already running. Right now we are using named mutexes with checking of running processes.
The goal is to prevent security attacks (as this is security software). My idea right now is that "bulletproof" solution is only to write an driver, that will serve this kind of information and will authenticate client via signed binaries.
Does anyone solved such problem?
What are your opinions and recommendations?
First, let me say that there is ultimately no way to protect your process from agents that have administrator or system access. Even if you write a rootkit driver that intercepts all system calls (a difficult and unsafe practice in of itself), there are still ways to use admin access to get in. You have the wrong design if this is a requirement.
If you set up your secure process to run as a service, you can use the Service Control Manager to start it. The SCM will only start one instance, will monitor that it stays up, allow you to define actions to execute if it crashes, and allow you to query the current status. Since this is controlled by the SCM and the service database can only be modified by administrators, an attacking process would not be able to spoof it.
I don't think there's a secure way of doing this. No matter what kind of system-unique, or user-unique named object you use - malicious 3rd party software can still use the exact same name and that would prevent your application from starting at all.
If you use the method of checking the currently executing processes, and checking if no executable with the same name is running - you'd run into problems, if the malicious software has the same executable name. If you also check the path, of that executable - then it would be possible to run two copies of your app from different locations.
If you create/delete a file when starting/finishing - that might be tricked as well.
The only thing that comes to my mind is you may be able to achieve the desired effect by putting all the logic of your app into a COM object, and then have a GUI application interact with it through COM interfaces. This would, only ensure, that there is only one COM object - you would be able to run as many GUI clients as you want. Note, that I'm not suggesting this as a bulletproof method - it may have it's own holes (for example - someone could make your GUI client to connect to a 3rd party COM object, by simply editing the registry).
So, the short answer - there is no truly secure way of doing this.
I use a named pipe¹, where the name is derived from the conditions that must be unique:
Name of the application (this is not the file name of the executable)
Username of the user who launched the application
If the named pipe creation fails because a pipe with that name already exists, then I know an instance is already running. I use a second lock around this check for thread (process) safety. The named pipe is automatically closed when the application terminates (even if the termination was due to an End Process command).
¹ This may not be the best general option, but in my case I end up sending data on it at a later point in the application lifetime.
In pseudo code:
numberofapps = 0
for each process in processes
if path to module file equals path to this module file
increment numberofapps
if number of apps > 1
exit
See msdn.microsoft.com/en-us/library/ms682623(VS.85).aspx for details on how to enumerate processes.
I've developed a windows application that uses shared memory---that is---memory mapped files for interprocess communication. I have a windows service that does some processing and periodically writes data to the memory mapped file. I have a separate windows application that reads from the memory mapped file and displays the information. The application works as expected on Windows XP, XP Pro and Server 2003, but NOT on Vista.
I can see that the data being written to the memory mapped file is happening correctly by the windows service because I can open the file with a text editor and see the stored messages, but the "consumer" application can't read from the file. One interesting thing to note here, is that if I close the consumer application and restart it, it consumes the messages that were previously written to the memory mapped file.
Also, another strange thing is that I get the same behavior when I connect to the windows host using Remote Desktop and invoke/use the consumer application through remote desktop. However, if I invoke the Remote Desktop and connect to the target host's console session with the following command: mstsc -v:servername /F -console, everything works perfectly.
So that's why I think the problem is related to permissions. Can anyone comment on this?
EDIT:
The ACL that I'm using to create the memory mapped file and the Mutex objects that sychronize access is as follows:
TCHAR * szSD = TEXT("D:")
TEXT("(A;;RPWPCCDCLCSWRCWDWOGAFA;;;S-1-1-0)")
TEXT("(A;;GA;;;BG)")
TEXT("(A;;GA;;;AN)")
TEXT("(A;;GA;;;AU)")
TEXT("(A;;GA;;;LS)")
TEXT("(A;;GA;;;RD)")
TEXT("(A;;GA;;;WD)")
TEXT("(A;;GA;;;BA)");
I think this may be part of the issue.
So I found the solution to my problem:
On Windows XP, all named kernel objects such as mutex, semaphore and memory mapped objects are stored in the same namespace. So when different processes in different user sessions reference a particular object using it's name, they obtain a handle to that object. However, as a security precaution, Windows terminal services creates a separate namespace for kernel objects referenced from processes started in it's session. Windows Vista has this behavior built into it as well, so that's why my app didn't work correctly on Vista. To elaborate, I have a Windows service that runs in the null session and an application that runs in a user session, so my named objects were being created in separate namespaces.
The quick fix for this issue was to use the Global namespace by prepending "Global\" to each kernel object name that I used and that did the trick.
The prefix "Global\" may not work on shared memory. See "Impact of Session 0 Isolation on Services and Drivers in Windows Vista" for solution.
What access are you opening the shared memory section with? Try with FILE_MAP_ALL_ACCESS and work your way down. Also make sure you don't have a race condition between the producer and consumers - which one is creating the shared memory? Make sure ths is created before the other one tries to open it. One method is to create the section in the parent before you start the child process - if you are using a parent/child architecture.
Your child may need to run elevated on Vista in order to be allowed access to the shared memory. It may also be related to the window session your are using. Services run in session 0 (I think) while other apps (especially if you log in via remote desktop) may run in another session.
Have you tried moving the file to a different location. Try putting it in the 'Shared Documents' folder, this seems to be the most freely accessible folder in Vista.