Monday, March 21, 2011

Anti Dll Injection

Dll injection is a dangerous technique which has the purpose of executing code into another process space, which is potentially the behavior of a malware. To do it is quite simple, the most known way is opening the target process with OpenProcess(), getting a handle, using VirtualAllocEx() to allocate memory in the target process, WriteProcessMemory() to write dll's name into the target process and then calling CreateRemoteThread():

HANDLE WINAPI CreateRemoteThread(
  __in   HANDLE hProcess,
  __in   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in   SIZE_T dwStackSize,
  __in   LPTHREAD_START_ROUTINE lpStartAddress,
  __in   LPVOID lpParameter,
  __in   DWORD dwCreationFlags,
  __out  LPDWORD lpThreadId

Where lpStartAddress is LoadLibraryA()'s address and lpParameter the address to the string which contains dll's name, so a thread is created into another process which loads a dll, however instead of loading a dll, anyone can use CreateRemoteThread() to create code caves which is an alternative to inject code without too much "noise".

To learn how to prevent dll injection we need to understand what really happens when a dll is loaded:

1 - First, when CreateRemoteThread() is called, a new thread is created into the target process and the entry point is LoadLibraryA() (quite obvious).

2 - LoadLibraryA() calls IsNLSDefinedString(), and it calls RtlInitAnsiStringEx() which copies the path+name of dll from the original
location to the stack of current thread.

2 - IsNLSDefinedString() calls RtlAnsiStringToUnicodeString() too, which creates the same string but a unicode version of it and stores in stack.

3 - After that, IsNLSDefinedString() returns, and LoadLibraryA() finally calls LdrLoadDll().

The picture below ilustrates the whole thing:

Some programmers usually hook LoadLibraryA() to prevent dll injection, but it's not efective at all if LdrLoadDll() is used instead of LoadLibraryA(), so if you're going to hook, be sure it's LdrLoadDll(). However if you do that, the program won't be able to load ANY dll anymore, so it can lead to problems in some cases.

Other options are quite possible, like hooking LdrLoadDll() or RtlInitAnsiStringEx() and trying to search for suspicious strings, or even taking the whole path+name of dll, and compare with the allowed ones, that's the best solution in my humble opinion.

If you do not know how to make a ring3 hook, check out my previous post, and learn how to do it.

Any question, please let me know...


1 comment:

Anonymous said...

Mas ainda é possível injetar uma DLL apartir do Ring 0.

Post a Comment