Injecting a dll into "services.exe" process in Windows 8.1 seems to be problematic.
InjectLibrary() returns true, but the dll is not loaded into services.exe.
But the same code works perfectly in Windows 7/XP.
Is there any way to work around this issue?
http://msdn.microsoft.com/en-us/library ... s.85).aspx
At this point I don't think there's much we can do about it, unfortunately...
Services.exe is considered one of these processes. You'll not be able to inject from usermode any longer into any of these protected processes
A list of these protected processes can be seen here
In testing scenarios only I've hacked around this by passing down the PID of the caller process and the PID of the target to the driver, opened the target process (specifying usermode handle) in the context of the calling process (KeStackAttachProcess) and passed the returned handle back to the caller. It's not something I'd offer to the public since it "ruins" the process' integrity and it's no longer considered protected. The nice way is to check a process with PsIsProtectedProcess from within the driver and not inject into it which I do in my own injection library.
Some context: We're creators of 0patch (https://0patch.com) and we want to be able to patch as many processes as possible. A few days ago we wrote a micropatch for Windows Defender (CVE-2017-0290) and it works nicely as long as WinDefend service is unprotected (we turned off protection to be able to debug into it). As soon as it is protected again, our DLL stops getting injected - and it's clear why, but we're looking for ways to provide patching to protected services without diminishing their security. So unprotecting them is clearly out of the question. If we could run our service as a protected service, I believe it still wouldn't be enough to inject into another protected service as to my understanding of Microsoft's docs, a protected process only allows loading DLLs that were signed with the same cert as itself (or by Microsoft).
(Btw, madshi, would you consider implementing the method described by iconic if it turned out to be reliable?)
The most secure way, without disabling any protection of a "protected process", is to enable the protected process field in your own process (located in your EPROCESS structure) instead of removing the bit (Vista) now turned byte (later OS). Since "protected processes" can access other protected processes uninhibited (whole address space) this would make more logical sense to me and not compromise security in the least bit at all. Now, this still wouldn't solve the DLL injection problem, since standard DLL injection (calling LoadLibrary etc.) which expects the DLL module to reside on disk would definitely trigger code signature checks. The only thing you could do is either locate the hash catalog and add your DLL to this list so that protected processes don't deny its load or you could skip traditional injection methods entirely and use the reflective DLL injection or manual mapping approach directly from memory this way you aren't using the OS's Ldr* APIs at all. Personally, I'd opt for the latter method and test it out. If you're just delivering "micro-patches" then by enabling your process to be protected allows you to use the standard OpenProcess/VirtualQueryEx/Read/WriteProcessMemory APIs without issue. Protected processes have evolved since initially making their debut in Vista, with the most popular example probably being AudioDg.exe or Mfpmp.exe. In Windows 8 and up you now have different sub-types and levels of protected signers.
P.S: The ruining of the process' integrity meaning behind my post from years ago referred to the dbgprint message that is output when a protected process attempts to load a DLL not in the approved hash catalog, the message states that the integrity is compromised or something to this effect. Do I think that it "breaks" or stops protection? No, especially since the DLL was blocked from loading in the first place however the system does notice this of course. In my injection library, as I mentioned in my old post, I specifically detect protected processes and do not attempt any injection at all on them since I know the load would ultimately fail or raise a red flag anyhow.