Recently while working on new version of RemoteDLL, I discovered interesting changes around DLL injection on Windows 8.



Before I actually talk about new changes, here is little background story. CreateRemoteThread is most common method used for DLL injection. It used to work flawlessly till Windows XP. However since Vista, it changed the colors, mainly it could no more inject DLL across sessions.  This was attributed to new ‘Session Separation’ feature introduced in Vista. To beat that limitation, we discovered new undocumented method NTCreateThread which could inject DLL across session boundaries on Vista/Win7.


Now while testing RemoteDLL on Windows 8, I tried (halfheartedly) injecting DLL into process running in Session 0. And to my utter surprise it worked just like magic in old days. I tried again to make sure that I am not dreaming 🙂




So it looks like M$ has put things back in order. The question arises whether CreateRemoteThread changes in Vista was done intently or accidentally. Because we could still use NTCreateThread with little risk. Quick analysis point us to other direction.

CreateRemoteThread actually calls NTCreateThread somewhere down the layer. May be some extra checking code that was added in Vista actually caused CreateRemoteThread to exit. So it is possible that this extra code was for something else but it adversely blocked injection across sessions. Now Microsoft may have realized the problem and must have fixed it to work normally. On the other hand, CreateRemoteThread have legitimate uses and certainly some of its big customers may have made the noise 🙂



To conclude, now CreateRemoteThread works well in Windows 8 across sessions (tested with consumer edition). However we still have to rely on NTCreateThread on Vista/Win7 for injection beyond session boundaries.



Another notable change that I have observed is w.r.t Reference Count or Load Count for DLLs.  Few years back, we have written research article ‘The covert way to find the Reference Count of DLL’ explaining about hidden/undocumented Load Count field in LDR_MODULE structure.


	struct _LDR_MODULE
	{
		LIST_ENTRY InLoadOrderModuleList;
		LIST_ENTRY InMemoryOrderModuleList;
		LIST_ENTRY InInitializationOrderModuleList;
		PVOID BaseAddress;
		PVOID EntryPoint;
		ULONG SizeOfImage;
		UNICODE_STRING FullDllName;
		UNICODE_STRING BaseDllName;
		ULONG Flags;
		USHORT LoadCount;
		USHORT TlsIndex;
		LIST_ENTRY HashTableEntry;
		ULONG TimeDateStamp;
	} LDR_MODULE, *PLDR_MODULE;


PEB within each process stores information on all Loaded DLLs in an linked list. Each dll in this list is represented by LDR_MODULE structure. One of the important but undocumented field here is ‘LoadCount’ (reference count of dll).

This ‘Load Count’ plays an important role in deciding when the DLL has to be completely unloaded from the process. It is also useful in Removing Injected DLL from the running process. Even our tools, RemoteDLL and SpyDLLRemover use it while removing Malware DLLs from process.



Here is the screenshot of RemoteDLL showing Load Count for all DLLs in selected process.



As you see LoadCount for static DLL is set to -1 as usual but for dynamically loaded DLLs it is set to 6. So where the hell it has gone? It has to be somewhere as every process needs it. It is possible that LDR_MODULE structure may have changed or some of its fields may have altered or it is moved somewhere else altogether. We have to dig further.



This is just the tip of iceberg, more reversing will reveal the real truths.  And as I discover more, I will put it here.  Meanwhile if you find any interesting things around it do share !